internal bool FilterHttpContext(HttpContextInfo ctx)
        {
            if (ChannelDispatcher == null)
            {
                return(true); // no mex can be involved.
            }
            if (ctx.Request.HttpMethod.ToUpper() != "GET")
            {
                return(!ChannelDispatcher.IsMex); // non-GET request never matches mex channel dispatcher.
            }
            var sme = ChannelDispatcher.Host.Extensions.Find <ServiceMetadataExtension> ();

            if (sme == null)
            {
                return(true); // no mex can be involved.
            }
            var listener = ChannelDispatcher.Listener;
            var mex      = sme.Instance;

            // now the request is GET, and we have to return true or false based on the matrix below:
            // matches wsdl or help| yes      |  no      |
            // mex                 | yes | no | yes | no |
            // --------------------+-----+----+-----+----+
            //                     |  T  | F  |  F  |  T |

            bool match =
                (mex.WsdlUrl != null && Uri.Compare(ctx.Request.Url, mex.WsdlUrl, cmpflag, fmtflag, StringComparison.Ordinal) == 0) ||
                (mex.HelpUrl != null && Uri.Compare(ctx.Request.Url, mex.HelpUrl, cmpflag, fmtflag, StringComparison.Ordinal) == 0);

            return(!(match ^ ChannelDispatcher.IsMex));
        }
Пример #2
0
        public bool TryDequeueRequest(ChannelDispatcher channel, TimeSpan timeout, out HttpContextInfo context)
        {
            DateTime start = DateTime.Now;

            context = null;
            var ce = Entries.FirstOrDefault(e => e.ChannelDispatcher == channel);

            if (ce == null)
            {
                return(false);
            }
            lock (ce.RetrieverLock) {
                var q = ce.ContextQueue;
                if (q.Count == 0)
                {
                    if (timeout.TotalMilliseconds < 0)
                    {
                        return(false);
                    }
                    TimeSpan waitTimeout = timeout;
                    if (timeout == TimeSpan.MaxValue)
                    {
                        waitTimeout = TimeSpan.FromMilliseconds(int.MaxValue);
                    }
                    bool ret = ce.WaitHandle.WaitOne(waitTimeout);
                    return(ret && TryDequeueRequest(channel, waitTimeout - (DateTime.Now - start), out context));                     // recurse, am lazy :/
                }
                context = q.Dequeue();
                return(true);
            }
        }
Пример #3
0
        protected HttpRequestMessageProperty CreateRequestProperty(HttpContextInfo ctxi)
        {
            var query = ctxi.Request.Url.Query;
            var prop  = new HttpRequestMessageProperty();

            prop.Method      = ctxi.Request.HttpMethod;
            prop.QueryString = query.StartsWith("?") ? query.Substring(1) : query;
            // FIXME: prop.SuppressEntityBody
            prop.Headers.Add(ctxi.Request.Headers);
            return(prop);
        }
Пример #4
0
 HttpChannelListenerEntry SelectChannel(HttpContextInfo ctx)
 {
     foreach (var e in Entries)
     {
         if (e.FilterHttpContext(ctx))
         {
             return(e);
         }
     }
     return(null);
 }
Пример #5
0
        public void ProcessNewContext(HttpContextInfo ctxi)
        {
            var ce = SelectChannel(ctxi);

            if (ce == null)
            {
                throw new InvalidOperationException("HttpListenerContext does not match any of the registered channels");
            }
            ce.ContextQueue.Enqueue(ctxi);
            ce.WaitHandle.Set();
        }
Пример #6
0
		public HttpRequestContext (HttpReplyChannel channel, HttpContextInfo context, Message request)
		{
			if (channel == null)
				throw new ArgumentNullException ("channel");
			if (context == null)
				throw new ArgumentNullException ("context");
			if (request == null)
				throw new ArgumentNullException ("request");
			this.channel = channel;
			this.context = context;
			this.request = request;
		}
Пример #7
0
 public HttpRequestContext (HttpReplyChannel channel, HttpContextInfo context, Message request)
 {
     if (channel == null)
         throw new ArgumentNullException ("channel");
     if (context == null)
         throw new ArgumentNullException ("context");
     if (request == null)
         throw new ArgumentNullException ("request");
     this.channel = channel;
     this.context = context;
     this.request = request;
 }
Пример #8
0
        protected Message CreatePostMessage(HttpContextInfo ctxi)
        {
            if (ctxi.Response.StatusCode != 200)               // it's already invalid.
            {
                ctxi.Close();
                return(null);
            }

            if (!Encoder.IsContentTypeSupported(ctxi.Request.ContentType))
            {
                ctxi.Response.StatusCode        = (int)HttpStatusCode.UnsupportedMediaType;
                ctxi.Response.StatusDescription = String.Format(
                    "Expected content-type '{0}' but got '{1}'", Encoder.ContentType, ctxi.Request.ContentType);
                ctxi.Close();

                return(null);
            }

            // FIXME: supply maxSizeOfHeaders.
            int maxSizeOfHeaders = 0x10000;

#if false // FIXME: enable it, once duplex callback test gets passed.
            Stream stream = ctxi.Request.InputStream;
            if (source.Source.TransferMode == TransferMode.Buffered)
            {
                if (ctxi.Request.ContentLength64 <= 0)
                {
                    throw new ArgumentException("This HTTP channel is configured to use buffered mode, and thus expects Content-Length sent to the listener");
                }
                long size = 0;
                var  ms   = new MemoryStream();
                var  buf  = new byte [0x1000];
                while (size < ctxi.Request.ContentLength64)
                {
                    if ((size += stream.Read(buf, 0, 0x1000)) > source.Source.MaxBufferSize)
                    {
                        throw new QuotaExceededException("Message quota exceeded");
                    }
                    ms.Write(buf, 0, (int)(size - ms.Length));
                }
                ms.Position = 0;
                stream      = ms;
            }

            var msg = Encoder.ReadMessage(
                stream, maxSizeOfHeaders, ctxi.Request.ContentType);
#else
            var msg = Encoder.ReadMessage(
                ctxi.Request.InputStream, maxSizeOfHeaders, ctxi.Request.ContentType);
#endif

            if (MessageVersion.Envelope.Equals(EnvelopeVersion.Soap11) ||
                MessageVersion.Addressing.Equals(AddressingVersion.None))
            {
                string action = GetHeaderItem(ctxi.Request.Headers ["SOAPAction"]);
                if (action != null)
                {
                    if (action.Length > 2 && action [0] == '"' && action [action.Length] == '"')
                    {
                        action = action.Substring(1, action.Length - 2);
                    }
                    msg.Headers.Action = action;
                }
            }
            msg.Properties.Add(RemoteEndpointMessageProperty.Name, new RemoteEndpointMessageProperty(ctxi.Request.ClientIPAddress, ctxi.Request.ClientPort));

            return(msg);
        }
Пример #9
0
		protected Message CreatePostMessage (HttpContextInfo ctxi)
		{
			if (ctxi.Response.StatusCode != 200) { // it's already invalid.
				ctxi.Close ();
				return null;
			}

			if (!Encoder.IsContentTypeSupported (ctxi.Request.ContentType)) {
				ctxi.Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType;
				ctxi.Response.StatusDescription = String.Format (
						"Expected content-type '{0}' but got '{1}'", Encoder.ContentType, ctxi.Request.ContentType);
				ctxi.Close ();

				return null;
			}

			// FIXME: supply maxSizeOfHeaders.
			int maxSizeOfHeaders = 0x10000;

#if false // FIXME: enable it, once duplex callback test gets passed.
			Stream stream = ctxi.Request.InputStream;
			if (source.Source.TransferMode == TransferMode.Buffered) {
				if (ctxi.Request.ContentLength64 <= 0)
					throw new ArgumentException ("This HTTP channel is configured to use buffered mode, and thus expects Content-Length sent to the listener");
				long size = 0;
				var ms = new MemoryStream ();
				var buf = new byte [0x1000];
				while (size < ctxi.Request.ContentLength64) {
					if ((size += stream.Read (buf, 0, 0x1000)) > source.Source.MaxBufferSize)
						throw new QuotaExceededException ("Message quota exceeded");
					ms.Write (buf, 0, (int) (size - ms.Length));
				}
				ms.Position = 0;
				stream = ms;
			}

			var msg = Encoder.ReadMessage (
				stream, maxSizeOfHeaders, ctxi.Request.ContentType);
#else
			var msg = Encoder.ReadMessage (
				ctxi.Request.InputStream, maxSizeOfHeaders, ctxi.Request.ContentType);
#endif

			if (MessageVersion.Envelope.Equals (EnvelopeVersion.Soap11) ||
			    MessageVersion.Addressing.Equals (AddressingVersion.None)) {
				string action = GetHeaderItem (ctxi.Request.Headers ["SOAPAction"]);
				if (action != null) {
					if (action.Length > 2 && action [0] == '"' && action [action.Length] == '"')
						action = action.Substring (1, action.Length - 2);
					msg.Headers.Action = action;
				}
			}

			return msg;
		}
Пример #10
0
		protected HttpRequestMessageProperty CreateRequestProperty (HttpContextInfo ctxi)
		{
			var query = ctxi.Request.Url.Query;
			var prop = new HttpRequestMessageProperty ();
			prop.Method = ctxi.Request.HttpMethod;
			prop.QueryString = query.StartsWith ("?") ? query.Substring (1) : query;
			// FIXME: prop.SuppressEntityBody
			prop.Headers.Add (ctxi.Request.Headers);
			return prop;
		}
Пример #11
0
		protected Message CreatePostMessage (HttpContextInfo ctxi)
		{
			if (ctxi.Response.StatusCode != 200) { // it's already invalid.
				ctxi.Close ();
				return null;
			}

			if (!Encoder.IsContentTypeSupported (ctxi.Request.ContentType)) {
				ctxi.Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType;
				ctxi.Response.StatusDescription = String.Format (
						"Expected content-type '{0}' but got '{1}'", Encoder.ContentType, ctxi.Request.ContentType);
				ctxi.Close ();

				return null;
			}

			// FIXME: supply maxSizeOfHeaders.
			int maxSizeOfHeaders = 0x10000;

			var msg = Encoder.ReadMessage (
				ctxi.Request.InputStream, maxSizeOfHeaders, ctxi.Request.ContentType);

			if (MessageVersion.Envelope.Equals (EnvelopeVersion.Soap11) ||
			    MessageVersion.Addressing.Equals (AddressingVersion.None)) {
				string action = GetHeaderItem (ctxi.Request.Headers ["SOAPAction"]);
				if (action != null) {
					if (action.Length > 2 && action [0] == '"' && action [action.Length] == '"')
						action = action.Substring (1, action.Length - 2);
					msg.Headers.Action = action;
				}
			}

			return msg;
		}