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)); }
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); } }
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); }
HttpChannelListenerEntry SelectChannel(HttpContextInfo ctx) { foreach (var e in Entries) { if (e.FilterHttpContext(ctx)) { return(e); } } return(null); }
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(); }
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; }
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); }
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; }
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; }
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; }