SdlChannelSink.cs

 
  1. // ==++==
  2. // 
  3. //   
  4. //    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5. //   
  6. //    The use and distribution terms for this software are contained in the file
  7. //    named license.txt, which can be found in the root of this distribution.
  8. //    By using this software in any fashion, you are agreeing to be bound by the
  9. //    terms of this license.
  10. //   
  11. //    You must not remove this notice, or any other, from this software.
  12. //   
  13. // 
  14. // ==--==
  15. //==========================================================================
  16. //  File:       SdlChannelSink.cs
  17. //
  18. //  Summary:    Sdl channel sink for generating sdl dynamically on the server.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.Collections;
  23. using System.Globalization;
  24. using System.IO;
  25. using System.Reflection;
  26. using System.Runtime.Remoting.Channels;
  27. using System.Runtime.Remoting.Channels.Http;
  28. using System.Runtime.Remoting.Messaging;
  29. using System.Text;
  30. namespace System.Runtime.Remoting.MetadataServices
  31. {
  32.     /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider"]/*' />
  33.     public class SdlChannelSinkProvider : IServerChannelSinkProvider
  34.     {
  35.         private IServerChannelSinkProvider _next = null;
  36.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider.SdlChannelSinkProvider"]/*' />
  37.         public SdlChannelSinkProvider()
  38.         {
  39.         }
  40.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider.SdlChannelSinkProvider1"]/*' />
  41.         public SdlChannelSinkProvider(IDictionary properties, ICollection providerData)
  42.         {
  43.         }
  44.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider.GetChannelData"]/*' />
  45.         public void GetChannelData(IChannelDataStore localChannelData)
  46.         {
  47.         }
  48.    
  49.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider.CreateSink"]/*' />
  50.         public IServerChannelSink CreateSink(IChannelReceiver channel)
  51.         {
  52.             IServerChannelSink nextSink = null;
  53.             if (_next != null)
  54.                 nextSink = _next.CreateSink(channel);
  55.             return new SdlChannelSink(channel, nextSink);
  56.         }
  57.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSinkProvider.Next"]/*' />
  58.         public IServerChannelSinkProvider Next
  59.         {
  60.             get { return _next; }
  61.             set { _next = value; }
  62.         }
  63.     } // class SdlChannelSinkProvider
  64.    
  65.     
  66.     /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink"]/*' />
  67.     public class SdlChannelSink : IServerChannelSink
  68.     {
  69.         private IChannelReceiver _receiver;
  70.         private IServerChannelSink _nextSink; 
  71.     
  72.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.SdlChannelSink"]/*' />
  73.         public SdlChannelSink(IChannelReceiver receiver, IServerChannelSink nextSink)
  74.         {
  75.             _receiver = receiver;
  76.             _nextSink = nextSink;
  77.         } // SdlChannelSink
  78.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.ProcessMessage"]/*' />
  79.         public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
  80.             IMessage requestMsg,
  81.             ITransportHeaders requestHeaders, Stream requestStream,
  82.             out IMessage responseMsg, out ITransportHeaders responseHeaders, 
  83.             out Stream responseStream)
  84.         {
  85.             if (requestMsg != null)
  86.             {
  87.                 // The message has already been deserialized so delegate to the next sink.
  88.                 return _nextSink.ProcessMessage(
  89.                     sinkStack,
  90.                     requestMsg, requestHeaders, requestStream, 
  91.                     out responseMsg, out responseHeaders, out responseStream);
  92.             }
  93.         
  94.             SdlType sdlType;
  95.             if (!ShouldIntercept(requestHeaders, out sdlType))
  96.                 return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream,
  97.                                                 out responseMsg, out responseHeaders, out responseStream);
  98.             // generate sdl and return it
  99.             responseHeaders = new TransportHeaders();
  100.             GenerateSdl(sdlType, sinkStack, requestHeaders, responseHeaders, out responseStream);
  101.             responseMsg = null;
  102.             return ServerProcessing.Complete;            
  103.         } // ProcessMessage
  104.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.AsyncProcessResponse"]/*' />
  105.         public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state,
  106.                                          IMessage msg, ITransportHeaders headers, Stream stream)
  107.         {
  108.             // We don't need to implement this because we never push ourselves to the sink
  109.             //   stack.
  110.         } // AsyncProcessResponse
  111.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.GetResponseStream"]/*' />
  112.         public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state,
  113.                                         IMessage msg, ITransportHeaders headers)
  114.         {
  115.             // We don't need to implement this because we never push ourselves
  116.             //   to the sink stack.
  117.             throw new NotSupportedException();
  118.         } // GetResponseStream
  119.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.NextChannelSink"]/*' />
  120.         public IServerChannelSink NextChannelSink
  121.         {
  122.             get { return _nextSink; }
  123.         }
  124.         /// <include file='doc/SdlChannelSink.uex' path='docs/doc[@for="SdlChannelSink.Properties"]/*' />
  125.         public IDictionary Properties
  126.         {
  127.             get { return null; }
  128.         } // Properties
  129.         // Should we intercept the call and return some SDL
  130.         private bool ShouldIntercept(ITransportHeaders requestHeaders, out SdlType sdlType)
  131.         {
  132.             sdlType = SdlType.Sdl;
  133.             
  134.             String requestVerb = requestHeaders["__RequestVerb"as String;
  135.             String requestURI = requestHeaders["__RequestUri"as String;
  136.     
  137.             // http verb must be "GET" to return sdl (and request uri must be set)
  138.             if ((requestURI == null) ||
  139.                 (requestVerb == null) || !requestVerb.Equals("GET"))              
  140.                 return false;
  141.             // find last index of ? and look for "sdl" or "sdlx"
  142.             int index = requestURI.LastIndexOf('?');
  143.             if (index == -1)
  144.                 return false// no query string
  145.             String queryString = requestURI.Substring(index).ToLower(CultureInfo.InvariantCulture);
  146.             // sdl?
  147.             if ((String.CompareOrdinal(queryString, "?sdl") == 0) ||
  148.                 (String.CompareOrdinal(queryString, "?sdlx") == 0))
  149.             { 
  150.                 sdlType = SdlType.Sdl;
  151.                 return true;
  152.             }
  153.             // wsdl?
  154.             if (String.CompareOrdinal(queryString, "?wsdl") == 0)
  155.             { 
  156.                 sdlType = SdlType.Wsdl;
  157.                 return true;
  158.             }            
  159.             
  160.             return false;            
  161.         } // ShouldIntercept
  162.         private void GenerateSdl(SdlType sdlType,
  163.                                  IServerResponseChannelSinkStack sinkStack,
  164.                                  ITransportHeaders requestHeaders,
  165.                                  ITransportHeaders responseHeaders,
  166.                                  out Stream outputStream)
  167.         {
  168.             String requestUri = requestHeaders[CommonTransportKeys.RequestUri] as String;           
  169.             String objectUri = HttpChannelHelper.GetObjectUriFromRequestUri(requestUri);
  170.             // If the host header is present, we will use this in the generated uri's
  171.             String hostName = (String)requestHeaders["Host"];
  172.             if (hostName != null)
  173.             {
  174.                 // filter out port number if present
  175.                 int index = hostName.IndexOf(':');
  176.                 if (index != -1)
  177.                     hostName = hostName.Substring(0, index);
  178.             }
  179.             
  180.             ServiceType[] types = null;
  181.             if (String.Compare(objectUri, "RemoteApplicationMetadata.rem"true, CultureInfo.InvariantCulture) == 0)
  182.             {
  183.                 // get the service description for all registered service types
  184.                 
  185.                 ActivatedServiceTypeEntry[] activatedTypes = 
  186.                     RemotingConfiguration.GetRegisteredActivatedServiceTypes();
  187.                 WellKnownServiceTypeEntry[] wellKnownTypes = 
  188.                     RemotingConfiguration.GetRegisteredWellKnownServiceTypes();
  189.                 // determine total number of types
  190.                 int typeCount = 0;
  191.                 
  192.                 if (activatedTypes != null)
  193.                     typeCount += activatedTypes.Length;
  194.                     
  195.                 if (wellKnownTypes != null)
  196.                     typeCount += wellKnownTypes.Length;
  197.                 types = new ServiceType[typeCount];
  198.                 // collect data
  199.                 int co = 0;
  200.                 if (activatedTypes != null)
  201.                 {
  202.                     foreach (ActivatedServiceTypeEntry entry in activatedTypes)
  203.                     {
  204.                         types[co++] = new ServiceType(entry.ObjectType, null);
  205.                     }                    
  206.                 }
  207.                 if (wellKnownTypes != null)
  208.                 {
  209.                     foreach (WellKnownServiceTypeEntry entry in wellKnownTypes)
  210.                     {   
  211.                         String[] urls = _receiver.GetUrlsForUri(entry.ObjectUri);
  212.                         String url = urls[0];
  213.                         if (hostName != null)
  214.                             url = HttpChannelHelper.ReplaceMachineNameWithThisString(url, hostName);
  215.                         types[co++] = new ServiceType(entry.ObjectType, url);
  216.                     } 
  217.                 }
  218.                 InternalRemotingServices.RemotingAssert(co == typeCount, "Not all types were processed.");                
  219.             }
  220.             else
  221.             {    
  222.                 // get the service description for a particular object
  223.                 Type objectType = RemotingServices.GetServerTypeForUri(objectUri);
  224.                 if (objectType == null)
  225.                 {
  226.                     throw new RemotingException(
  227.                         String.Format(
  228.                             "Object with uri '{0}' does not exist at server.",
  229.                             objectUri));
  230.                 }
  231.                 
  232.                 String[] urls = _receiver.GetUrlsForUri(objectUri);
  233.                 String url = urls[0];
  234.                 if (hostName != null)
  235.                     url = HttpChannelHelper.ReplaceMachineNameWithThisString(url, hostName);
  236.                 types = new ServiceType[1];
  237.                 types[0] = new ServiceType(objectType, url);
  238.             }
  239.             responseHeaders["Content-Type"] = "text/xml";
  240.             bool bMemStream = false;
  241.             outputStream = sinkStack.GetResponseStream(null, responseHeaders);
  242.             if (outputStream == null)
  243.             {
  244.                 outputStream = new MemoryStream(1024);
  245.                 bMemStream = true;
  246.             }        
  247.             MetaData.ConvertTypesToSchemaToStream(types, sdlType, outputStream);
  248.             if (bMemStream)
  249.                 outputStream.Position = 0;
  250.         } // GenerateXmlForUri               
  251.         
  252.     } // class SdlChannelSink
  253. // namespace System.Runtime.Remoting.Channnels
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值