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
- CodeGroup.cs
- PropertyEmitterBase.cs
- ServiceProviders.cs
- TreeNodeConverter.cs
- ComPlusSynchronizationContext.cs
- Quaternion.cs
- SetUserPreferenceRequest.cs
- ExpressionNode.cs
- WizardStepCollectionEditor.cs
- GeneralTransformCollection.cs
- XXXOnTypeBuilderInstantiation.cs
- FileDialogPermission.cs
- SendingRequestEventArgs.cs
- SoapSchemaExporter.cs
- ServiceBusyException.cs
- Deflater.cs
- EventDescriptor.cs
- ExportFileRequest.cs
- WasNotInstalledException.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- CounterCreationData.cs
- FileDialog.cs
- XPathExpr.cs
- CacheMode.cs
- PointKeyFrameCollection.cs
- QueryOutputWriter.cs
- WhitespaceSignificantCollectionAttribute.cs
- documentsequencetextview.cs
- FixUpCollection.cs
- SystemIPAddressInformation.cs
- ListControlStringCollectionEditor.cs
- CredentialCache.cs
- ConfigurationValidatorBase.cs
- WebBrowser.cs
- CodeExpressionCollection.cs
- ToolStripContentPanel.cs
- FileLogRecordHeader.cs
- FloatSumAggregationOperator.cs
- CharKeyFrameCollection.cs
- RestHandler.cs
- SelectorAutomationPeer.cs
- DbExpressionBuilder.cs
- MessageDecoder.cs
- ColumnPropertiesGroup.cs
- MimeWriter.cs
- RtfToXamlReader.cs
- DBAsyncResult.cs
- InternalBufferOverflowException.cs
- ListMarkerLine.cs
- NullableIntSumAggregationOperator.cs
- SHA1Managed.cs
- XmlConvert.cs
- NameSpaceExtractor.cs
- DataSpaceManager.cs
- SqlDependencyListener.cs
- DataGridViewToolTip.cs
- VerticalAlignConverter.cs
- BindToObject.cs
- RtfControls.cs
- ExpressionEditorSheet.cs
- UriGenerator.cs
- EdmValidator.cs
- CalloutQueueItem.cs
- TextRangeSerialization.cs
- ValidationSummary.cs
- ConfigXmlSignificantWhitespace.cs
- PassportIdentity.cs
- Help.cs
- GroupItemAutomationPeer.cs
- DataGridViewColumnDesigner.cs
- SqlRowUpdatingEvent.cs
- SerializationSectionGroup.cs
- ContentElementAutomationPeer.cs
- ExpressionHelper.cs
- TypeElement.cs
- CreateRefExpr.cs
- BinaryWriter.cs
- SwitchAttribute.cs
- XmlByteStreamReader.cs
- WebBaseEventKeyComparer.cs
- Int32Rect.cs
- BooleanAnimationBase.cs
- UnsafeCollabNativeMethods.cs
- ToolStripMenuItem.cs
- FormattedTextSymbols.cs
- IFormattable.cs
- SpoolingTask.cs
- WhitespaceRuleLookup.cs
- LogExtent.cs
- XmlWrappingWriter.cs
- BitConverter.cs
- HtmlObjectListAdapter.cs
- SqlComparer.cs
- ActivationServices.cs
- SimpleRecyclingCache.cs
- VirtualizedContainerService.cs
- XNodeNavigator.cs
- MetadataArtifactLoaderCompositeFile.cs
- XmlWhitespace.cs
- AuthenticatingEventArgs.cs