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
- DrawListViewSubItemEventArgs.cs
- PersonalizationEntry.cs
- Rule.cs
- XhtmlBasicPhoneCallAdapter.cs
- DesignerAttribute.cs
- QilNode.cs
- TreeIterator.cs
- OleDbDataReader.cs
- HyperLink.cs
- PenCursorManager.cs
- GridViewDeletedEventArgs.cs
- DesignerResources.cs
- SchemaMerger.cs
- NavigationWindowAutomationPeer.cs
- RequestTimeoutManager.cs
- SocketException.cs
- ProfessionalColorTable.cs
- XmlChildNodes.cs
- PermissionListSet.cs
- AlternateView.cs
- SchemaElementDecl.cs
- ChangeInterceptorAttribute.cs
- ToolStripTemplateNode.cs
- SystemIcmpV4Statistics.cs
- XamlTemplateSerializer.cs
- StringUtil.cs
- LinqDataSourceDeleteEventArgs.cs
- KoreanLunisolarCalendar.cs
- ResolveCriteriaCD1.cs
- DependencyObjectType.cs
- BmpBitmapDecoder.cs
- NotCondition.cs
- TagMapCollection.cs
- HttpListenerTimeoutManager.cs
- NameValuePermission.cs
- WaveHeader.cs
- PathTooLongException.cs
- LexicalChunk.cs
- FormViewModeEventArgs.cs
- CanonicalXml.cs
- RTTypeWrapper.cs
- XmlElementAttribute.cs
- LinqDataSource.cs
- SecurityUtils.cs
- ContainerControl.cs
- DataObjectEventArgs.cs
- SqlLiftWhereClauses.cs
- ObjectQuery_EntitySqlExtensions.cs
- EntityContainerEmitter.cs
- RemotingSurrogateSelector.cs
- __Filters.cs
- AttributeExtensions.cs
- WebUtility.cs
- HttpRequestCacheValidator.cs
- MemoryMappedFileSecurity.cs
- TemplateBindingExpression.cs
- Pair.cs
- CompressEmulationStream.cs
- CompilerScopeManager.cs
- CollectionType.cs
- TextContainerChangedEventArgs.cs
- RankException.cs
- SystemResourceKey.cs
- CodeIdentifiers.cs
- RSATokenProvider.cs
- CustomAttributeFormatException.cs
- TextCompositionEventArgs.cs
- GridItem.cs
- HttpStaticObjectsCollectionBase.cs
- QueueNameHelper.cs
- PrefixQName.cs
- CombinedGeometry.cs
- MetadataArtifactLoaderComposite.cs
- VirtualDirectoryMapping.cs
- RSAPKCS1SignatureDeformatter.cs
- WebPartCatalogCloseVerb.cs
- assemblycache.cs
- MachineKeySection.cs
- BackEase.cs
- AcceptorSessionSymmetricTransportSecurityProtocol.cs
- CultureNotFoundException.cs
- SHA512.cs
- shaperfactoryquerycacheentry.cs
- KeyInterop.cs
- DomainUpDown.cs
- OracleTransaction.cs
- SqlConnectionPoolProviderInfo.cs
- ValidationEventArgs.cs
- XmlByteStreamWriter.cs
- ExplicitDiscriminatorMap.cs
- WebPermission.cs
- ConnectionManagementSection.cs
- ScopedKnownTypes.cs
- GifBitmapEncoder.cs
- Calendar.cs
- DropShadowBitmapEffect.cs
- SymLanguageVendor.cs
- ObjectReferenceStack.cs
- SmiContext.cs
- DataSetUtil.cs