Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / HTTP / HTTPRemotingHandler.cs / 1305376 / HTTPRemotingHandler.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//==========================================================================
// File: HTTPRemotingHandler.cs
//
// Summary: Implements an ASP+ handler that forwards requests to the
// the remoting HTTP Channel.
//
// Classes: Derived from IHttpHandler
//
//
//=========================================================================
using System;
using System.DirectoryServices;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Messaging;
using System.Diagnostics;
using System.Web;
using System.Web.UI;
using System.Runtime.Remoting.MetadataServices;
using System.Globalization;
using System.Collections.Specialized;
namespace System.Runtime.Remoting.Channels.Http
{
public class HttpRemotingHandler : IHttpHandler
{
//Handler Specific
private static String ApplicationConfigurationFile = "web.config";
private static bool bLoadedConfiguration = false;
private static HttpHandlerTransportSink s_transportSink = null; // transport sink
// If an exception occurs while we are configuring the app domain, it is not possible
// to recover since remoting is in an indeterminate state, so we will return that
// exception every time.
private static Exception s_fatalException = null;
public HttpRemotingHandler()
{
}
///
public HttpRemotingHandler(Type type, Object srvID)
{
}
//
// Process the ASP+ Request
//
public void ProcessRequest(HttpContext context)
{
InternalProcessRequest(context);
}
//
// Internal
//
// Transform the ASP+ Request and Response Structures in
// Channel Structures:
// ** Request.ServerVariables
// ** Request.InputStream
// ** Response.Headers
//
// This is needed to reduce the between dependency COR Channels
// and ASP+
//
private void InternalProcessRequest(HttpContext context)
{
try
{
HttpRequest httpRequest = context.Request;
// check if have previously loaded configuration
if (!bLoadedConfiguration)
{
// locking a random static variable, so we can lock the class
lock(HttpRemotingHandler.ApplicationConfigurationFile)
{
if (!bLoadedConfiguration)
{
// Initialize IIS information
IisHelper.Initialize();
// set application name
if (RemotingConfiguration.ApplicationName == null)
RemotingConfiguration.ApplicationName = httpRequest.ApplicationPath;
String filename = String.Concat(httpRequest.PhysicalApplicationPath,
ApplicationConfigurationFile);
if (File.Exists(filename))
{
try
{
RemotingConfiguration.Configure(filename, false/*enableSecurity*/);
}
catch (Exception e)
{
s_fatalException = e;
WriteException(context, e);
return;
}
}
try
{
// do a search for a registered channel that wants to listen
IChannelReceiverHook httpChannel = null;
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
IChannelReceiverHook hook = channel as IChannelReceiverHook;
if (hook != null)
{
if (String.Compare(hook.ChannelScheme, "http", StringComparison.OrdinalIgnoreCase) == 0)
{
if (hook.WantsToListen)
{
httpChannel = hook;
break;
}
}
}
}
if (httpChannel == null)
{
// No http channel that was listening found.
// Create a new channel.
HttpChannel newHttpChannel = new HttpChannel();
ChannelServices.RegisterChannel(newHttpChannel, false/*enableSecurity*/);
httpChannel = newHttpChannel;
}
String scheme = null;
if (IisHelper.IsSslRequired)
scheme = "https";
else
scheme = "http";
String hookChannelUri =
scheme + "://" + CoreChannel.GetMachineIp();
int port = context.Request.Url.Port;
String restOfUri = ":" + port + "/" + RemotingConfiguration.ApplicationName;
hookChannelUri += restOfUri;
// add hook uri for this channel
httpChannel.AddHookChannelUri(hookChannelUri);
// If it uses ChannelDataStore, re-retrieve updated url in case it was updated.
ChannelDataStore cds = ((IChannelReceiver)httpChannel).ChannelData as ChannelDataStore;
if (cds != null)
hookChannelUri = cds.ChannelUris[0];
IisHelper.ApplicationUrl = hookChannelUri;
// This is a hack to refresh the channel data.
// In V-Next, we will add a ChannelServices.RefreshChannelData() api.
ChannelServices.UnregisterChannel(null);
s_transportSink = new HttpHandlerTransportSink(httpChannel.ChannelSinkChain);
}
catch (Exception e)
{
s_fatalException = e;
WriteException(context, e);
return;
}
bLoadedConfiguration = true;
}
}
}
if (s_fatalException == null)
{
if (!CanServiceRequest(context))
WriteException(context, new RemotingException(CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished")));
else
s_transportSink.HandleRequest(context);
}
else
WriteException(context, s_fatalException);
}
catch (Exception e)
{
WriteException(context, e);
}
} // InternalProcessRequest
public bool IsReusable { get { return true; } }
string ComposeContentType(string contentType, Encoding encoding) {
if (encoding != null) {
StringBuilder sb = new StringBuilder(contentType);
sb.Append("; charset=");
sb.Append(encoding.WebName);
return sb.ToString();
}
else
return contentType;
}
bool CanServiceRequest(HttpContext context) {
//Need to get the object uri first (cannot have query string)
string requestUri = GetRequestUriForCurrentRequest(context);
string objectUri = HttpChannelHelper.GetObjectUriFromRequestUri(requestUri);
context.Items["__requestUri"] = requestUri;
if (String.Compare(context.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase) != 0) {
//If the request backed by an existing object
if (RemotingServices.GetServerTypeForUri(requestUri) != null)
return true;
}
else {
if (context.Request.QueryString.Count != 1)
return false;
string[] values = context.Request.QueryString.GetValues(0);
if (values.Length != 1 || String.Compare(values[0], "wsdl", StringComparison.OrdinalIgnoreCase) != 0)
return false;
//If the request specifically asks for the wildcard
if (String.Compare(objectUri, "RemoteApplicationMetadata.rem", StringComparison.OrdinalIgnoreCase) == 0)
return true;
// find last index of ?
int index = requestUri.LastIndexOf('?');
if (index != -1)
requestUri = requestUri.Substring(0, index);
//If the request backed by an existing object
if (RemotingServices.GetServerTypeForUri(requestUri) != null)
return true;
}
//If the request is backed by an existing file on disk it should be serviced
if (File.Exists(context.Request.PhysicalPath))
return true;
return false;
}
string GetRequestUriForCurrentRequest(HttpContext context) {
// we need to pull off any http specific data plus the application v-dir name
String rawUrl = context.Request.RawUrl;
// here's where we pull off channel info
String channelUri;
String requestUri;
channelUri = HttpChannelHelper.ParseURL(rawUrl, out requestUri);
if (channelUri == null)
requestUri = rawUrl;
// here's where we pull off the application v-dir name
String appName = RemotingConfiguration.ApplicationName;
if (appName != null && appName.Length > 0 && requestUri.Length > appName.Length)
// "/appname" should always be in front, otherwise we wouldn't
// be in this handler.
requestUri = requestUri.Substring(appName.Length + 1);
return requestUri;
}
string GenerateFaultString(HttpContext context, Exception e) {
//If the user has specified it's a development server (versus a production server) in ASP.NET config,
//then we should just return e.ToString instead of extracting the list of messages.
if (!CustomErrorsEnabled(context))
return e.ToString();
else {
return CoreChannel.GetResourceString("Remoting_InternalError");
}
}
void WriteException(HttpContext context, Exception e) {
InternalRemotingServices.RemotingTrace("HttpHandler: Exception thrown...\n");
InternalRemotingServices.RemotingTrace(e.StackTrace);
Stream outputStream = context.Response.OutputStream;
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.ContentType = ComposeContentType("text/plain", Encoding.UTF8);
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.StatusDescription = CoreChannel.GetResourceString("Remoting_InternalError");
StreamWriter writer = new StreamWriter(outputStream, new UTF8Encoding(false));
writer.WriteLine(GenerateFaultString(context, e));
writer.Flush();
}
internal static bool IsLocal(HttpContext context) {
string localAddress = context.Request.ServerVariables["LOCAL_ADDR"];
string remoteAddress = context.Request.UserHostAddress;
return (context.Request.Url.IsLoopback || (localAddress != null && remoteAddress != null && localAddress == remoteAddress));
}
internal static bool CustomErrorsEnabled(HttpContext context) {
try {
if (!context.IsCustomErrorEnabled)
return false;
return RemotingConfiguration.CustomErrorsEnabled(IsLocal(context));
}
catch {
return true;
}
}
} // HttpRemotingHandler
public class HttpRemotingHandlerFactory : IHttpHandlerFactory
{
internal object _webServicesFactory = null;
internal static Type s_webServicesFactoryType = null;
// REMACT: internal static Type s_remActType = null;
internal static Object s_configLock = new Object();
internal static Hashtable s_registeredDynamicTypeTable = Hashtable.Synchronized(new Hashtable());
void DumpRequest(HttpContext context)
{
HttpRequest request = context.Request;
InternalRemotingServices.DebugOutChnl("Process Request called.");
InternalRemotingServices.DebugOutChnl("Path = " + request.Path);
InternalRemotingServices.DebugOutChnl("PhysicalPath = " + request.PhysicalPath);
//InternalRemotingServices.DebugOutChnl("QueryString = " + request.Url.QueryString);
InternalRemotingServices.DebugOutChnl("HttpMethod = " + request.HttpMethod);
InternalRemotingServices.DebugOutChnl("ContentType = " + request.ContentType);
InternalRemotingServices.DebugOutChnl("PathInfo = " + request.PathInfo);
/*
String[] keys = request.Headers.AllKeys;
String[] values = request.Headers.All;
for (int i=0; i
public HttpRemotingHandler(Type type, Object srvID)
{
}
//
// Process the ASP+ Request
//
public void ProcessRequest(HttpContext context)
{
InternalProcessRequest(context);
}
//
// Internal
//
// Transform the ASP+ Request and Response Structures in
// Channel Structures:
// ** Request.ServerVariables
// ** Request.InputStream
// ** Response.Headers
//
// This is needed to reduce the between dependency COR Channels
// and ASP+
//
private void InternalProcessRequest(HttpContext context)
{
try
{
HttpRequest httpRequest = context.Request;
// check if have previously loaded configuration
if (!bLoadedConfiguration)
{
// locking a random static variable, so we can lock the class
lock(HttpRemotingHandler.ApplicationConfigurationFile)
{
if (!bLoadedConfiguration)
{
// Initialize IIS information
IisHelper.Initialize();
// set application name
if (RemotingConfiguration.ApplicationName == null)
RemotingConfiguration.ApplicationName = httpRequest.ApplicationPath;
String filename = String.Concat(httpRequest.PhysicalApplicationPath,
ApplicationConfigurationFile);
if (File.Exists(filename))
{
try
{
RemotingConfiguration.Configure(filename, false/*enableSecurity*/);
}
catch (Exception e)
{
s_fatalException = e;
WriteException(context, e);
return;
}
}
try
{
// do a search for a registered channel that wants to listen
IChannelReceiverHook httpChannel = null;
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
IChannelReceiverHook hook = channel as IChannelReceiverHook;
if (hook != null)
{
if (String.Compare(hook.ChannelScheme, "http", StringComparison.OrdinalIgnoreCase) == 0)
{
if (hook.WantsToListen)
{
httpChannel = hook;
break;
}
}
}
}
if (httpChannel == null)
{
// No http channel that was listening found.
// Create a new channel.
HttpChannel newHttpChannel = new HttpChannel();
ChannelServices.RegisterChannel(newHttpChannel, false/*enableSecurity*/);
httpChannel = newHttpChannel;
}
String scheme = null;
if (IisHelper.IsSslRequired)
scheme = "https";
else
scheme = "http";
String hookChannelUri =
scheme + "://" + CoreChannel.GetMachineIp();
int port = context.Request.Url.Port;
String restOfUri = ":" + port + "/" + RemotingConfiguration.ApplicationName;
hookChannelUri += restOfUri;
// add hook uri for this channel
httpChannel.AddHookChannelUri(hookChannelUri);
// If it uses ChannelDataStore, re-retrieve updated url in case it was updated.
ChannelDataStore cds = ((IChannelReceiver)httpChannel).ChannelData as ChannelDataStore;
if (cds != null)
hookChannelUri = cds.ChannelUris[0];
IisHelper.ApplicationUrl = hookChannelUri;
// This is a hack to refresh the channel data.
// In V-Next, we will add a ChannelServices.RefreshChannelData() api.
ChannelServices.UnregisterChannel(null);
s_transportSink = new HttpHandlerTransportSink(httpChannel.ChannelSinkChain);
}
catch (Exception e)
{
s_fatalException = e;
WriteException(context, e);
return;
}
bLoadedConfiguration = true;
}
}
}
if (s_fatalException == null)
{
if (!CanServiceRequest(context))
WriteException(context, new RemotingException(CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished")));
else
s_transportSink.HandleRequest(context);
}
else
WriteException(context, s_fatalException);
}
catch (Exception e)
{
WriteException(context, e);
}
} // InternalProcessRequest
public bool IsReusable { get { return true; } }
string ComposeContentType(string contentType, Encoding encoding) {
if (encoding != null) {
StringBuilder sb = new StringBuilder(contentType);
sb.Append("; charset=");
sb.Append(encoding.WebName);
return sb.ToString();
}
else
return contentType;
}
bool CanServiceRequest(HttpContext context) {
//Need to get the object uri first (cannot have query string)
string requestUri = GetRequestUriForCurrentRequest(context);
string objectUri = HttpChannelHelper.GetObjectUriFromRequestUri(requestUri);
context.Items["__requestUri"] = requestUri;
if (String.Compare(context.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase) != 0) {
//If the request backed by an existing object
if (RemotingServices.GetServerTypeForUri(requestUri) != null)
return true;
}
else {
if (context.Request.QueryString.Count != 1)
return false;
string[] values = context.Request.QueryString.GetValues(0);
if (values.Length != 1 || String.Compare(values[0], "wsdl", StringComparison.OrdinalIgnoreCase) != 0)
return false;
//If the request specifically asks for the wildcard
if (String.Compare(objectUri, "RemoteApplicationMetadata.rem", StringComparison.OrdinalIgnoreCase) == 0)
return true;
// find last index of ?
int index = requestUri.LastIndexOf('?');
if (index != -1)
requestUri = requestUri.Substring(0, index);
//If the request backed by an existing object
if (RemotingServices.GetServerTypeForUri(requestUri) != null)
return true;
}
//If the request is backed by an existing file on disk it should be serviced
if (File.Exists(context.Request.PhysicalPath))
return true;
return false;
}
string GetRequestUriForCurrentRequest(HttpContext context) {
// we need to pull off any http specific data plus the application v-dir name
String rawUrl = context.Request.RawUrl;
// here's where we pull off channel info
String channelUri;
String requestUri;
channelUri = HttpChannelHelper.ParseURL(rawUrl, out requestUri);
if (channelUri == null)
requestUri = rawUrl;
// here's where we pull off the application v-dir name
String appName = RemotingConfiguration.ApplicationName;
if (appName != null && appName.Length > 0 && requestUri.Length > appName.Length)
// "/appname" should always be in front, otherwise we wouldn't
// be in this handler.
requestUri = requestUri.Substring(appName.Length + 1);
return requestUri;
}
string GenerateFaultString(HttpContext context, Exception e) {
//If the user has specified it's a development server (versus a production server) in ASP.NET config,
//then we should just return e.ToString instead of extracting the list of messages.
if (!CustomErrorsEnabled(context))
return e.ToString();
else {
return CoreChannel.GetResourceString("Remoting_InternalError");
}
}
void WriteException(HttpContext context, Exception e) {
InternalRemotingServices.RemotingTrace("HttpHandler: Exception thrown...\n");
InternalRemotingServices.RemotingTrace(e.StackTrace);
Stream outputStream = context.Response.OutputStream;
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.ContentType = ComposeContentType("text/plain", Encoding.UTF8);
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.StatusDescription = CoreChannel.GetResourceString("Remoting_InternalError");
StreamWriter writer = new StreamWriter(outputStream, new UTF8Encoding(false));
writer.WriteLine(GenerateFaultString(context, e));
writer.Flush();
}
internal static bool IsLocal(HttpContext context) {
string localAddress = context.Request.ServerVariables["LOCAL_ADDR"];
string remoteAddress = context.Request.UserHostAddress;
return (context.Request.Url.IsLoopback || (localAddress != null && remoteAddress != null && localAddress == remoteAddress));
}
internal static bool CustomErrorsEnabled(HttpContext context) {
try {
if (!context.IsCustomErrorEnabled)
return false;
return RemotingConfiguration.CustomErrorsEnabled(IsLocal(context));
}
catch {
return true;
}
}
} // HttpRemotingHandler
public class HttpRemotingHandlerFactory : IHttpHandlerFactory
{
internal object _webServicesFactory = null;
internal static Type s_webServicesFactoryType = null;
// REMACT: internal static Type s_remActType = null;
internal static Object s_configLock = new Object();
internal static Hashtable s_registeredDynamicTypeTable = Hashtable.Synchronized(new Hashtable());
void DumpRequest(HttpContext context)
{
HttpRequest request = context.Request;
InternalRemotingServices.DebugOutChnl("Process Request called.");
InternalRemotingServices.DebugOutChnl("Path = " + request.Path);
InternalRemotingServices.DebugOutChnl("PhysicalPath = " + request.PhysicalPath);
//InternalRemotingServices.DebugOutChnl("QueryString = " + request.Url.QueryString);
InternalRemotingServices.DebugOutChnl("HttpMethod = " + request.HttpMethod);
InternalRemotingServices.DebugOutChnl("ContentType = " + request.ContentType);
InternalRemotingServices.DebugOutChnl("PathInfo = " + request.PathInfo);
/*
String[] keys = request.Headers.AllKeys;
String[] values = request.Headers.All;
for (int i=0; i
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BrowserCapabilitiesCompiler.cs
- OutputScopeManager.cs
- XmlNotation.cs
- TimeEnumHelper.cs
- TypedTableHandler.cs
- StringAnimationUsingKeyFrames.cs
- SettingsPropertyNotFoundException.cs
- SoapSchemaImporter.cs
- WebPartUtil.cs
- keycontainerpermission.cs
- UniformGrid.cs
- SafeIUnknown.cs
- ImpersonateTokenRef.cs
- RichTextBoxContextMenu.cs
- XNodeValidator.cs
- FunctionCommandText.cs
- Misc.cs
- OpenTypeLayoutCache.cs
- MenuItem.cs
- HttpConfigurationContext.cs
- ActivitySurrogate.cs
- BitSet.cs
- figurelengthconverter.cs
- Walker.cs
- formatter.cs
- RelatedPropertyManager.cs
- PassportAuthenticationEventArgs.cs
- xml.cs
- ProviderConnectionPointCollection.cs
- TextDecorationUnitValidation.cs
- UnsafeCollabNativeMethods.cs
- WriterOutput.cs
- PngBitmapDecoder.cs
- RequestCachePolicyConverter.cs
- HttpServerVarsCollection.cs
- ScrollChrome.cs
- SecurityTraceRecordHelper.cs
- ProviderIncompatibleException.cs
- FamilyMapCollection.cs
- ResourceBinder.cs
- OpenTypeLayout.cs
- ControlIdConverter.cs
- XmlSchemaAnnotated.cs
- oledbmetadatacolumnnames.cs
- httpserverutility.cs
- SettingsPropertyCollection.cs
- OleDbFactory.cs
- EditingMode.cs
- TypeUtils.cs
- SQLMoneyStorage.cs
- TextDecorationCollection.cs
- InvokeMethodActivityDesigner.cs
- CompilerInfo.cs
- EntityProxyFactory.cs
- ExceptionHandlerDesigner.cs
- QueryStringParameter.cs
- SHA256Managed.cs
- HwndSource.cs
- DBNull.cs
- InputMethod.cs
- ExceptionUtil.cs
- COM2IManagedPerPropertyBrowsingHandler.cs
- ProxyBuilder.cs
- CodeDirectionExpression.cs
- BasicKeyConstraint.cs
- CommandManager.cs
- FreezableOperations.cs
- TrustLevelCollection.cs
- RetrieveVirtualItemEventArgs.cs
- OracleDataReader.cs
- WhitespaceRuleReader.cs
- GACIdentityPermission.cs
- Math.cs
- WebPartConnection.cs
- HierarchicalDataBoundControlAdapter.cs
- Menu.cs
- CornerRadius.cs
- UInt64Storage.cs
- DesignerRegionCollection.cs
- StoreContentChangedEventArgs.cs
- FlowDocumentPage.cs
- NamespaceDecl.cs
- BooleanToVisibilityConverter.cs
- CaseInsensitiveComparer.cs
- TracingConnectionInitiator.cs
- NullableConverter.cs
- basecomparevalidator.cs
- Invariant.cs
- PauseStoryboard.cs
- ObjectListCommandEventArgs.cs
- XmlUnspecifiedAttribute.cs
- SerialPinChanges.cs
- RegexCompiler.cs
- CancelAsyncOperationRequest.cs
- updateconfighost.cs
- TextPenaltyModule.cs
- SplitterPanel.cs
- RC2CryptoServiceProvider.cs
- TemplateParser.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs