/// <summary> /// Initializes a new instance. /// </summary> /// <param name="router"></param> /// <param name="transportElement"></param> /// <param name="context"></param> public AspNetCoreReplyChannelListener( AspNetCoreRequestRouter router, AspNetCoreTransportBindingElement transportElement, BindingContext context) : base(context.Binding) { this.router = router ?? throw new ArgumentNullException(nameof(router)); this.bufferManager = BufferManager.CreateBufferManager(transportElement.MaxBufferPoolSize, (int)transportElement.MaxReceivedMessageSize); this.encoderFactory = context.BindingParameters.Remove <MessageEncodingBindingElement>().CreateMessageEncoderFactory(); this.uri = AspNetCoreUri.GetUri(context.ListenUriBaseAddress.AbsolutePath + context.ListenUriRelativeAddress); this.sync = new SemaphoreSlim(5); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="next"></param> /// <param name="services"></param> /// <param name="binding"></param> AspNetCoreServiceHostMiddleware( RequestDelegate next, IServiceProvider services, AspNetCoreBinding binding) { this.next = next; this.services = services ?? throw new ArgumentNullException(nameof(services)); this.binding = binding ?? throw new ArgumentNullException(nameof(binding)); this.router = new AspNetCoreRequestRouter(); this.baseUri = AspNetCoreUri.GetUri("/" + Guid.NewGuid().ToString("N") + "/"); // register for cleanup when application is stopped services.GetRequiredService <IApplicationLifetime>().ApplicationStopping.Register(() => host.Close()); }
/// <summary> /// Routes the request to the appropriate queue and initiates a blockig send for completion. /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task RunAsync(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // acquire registered queue var queue = Get(AspNetCoreUri.GetUri(context)); if (queue == null) { throw new AspNetCoreServiceModelException($"Unable to route request '{context.Request.Path}'. No registered listener."); } // route to queue and wait for request to be handled await queue.SendAsync(context); }
/// <summary> /// Process addressing information from HTTP. /// </summary> /// <param name="context"></param> /// <param name="message"></param> void ReadMessageAddressing(HttpRequest request, Message message) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } // apply properties ReadProperties(request, message); // decide on the default port based on the schema int DefaultPort() { switch (request.Scheme) { case "http": return(80); case "https": return(443); default: return(80); } } // encode raw request URL into Via message.Properties.Via = new UriBuilder( request.Scheme, request.Host.Host, request.Host.Port ?? DefaultPort(), request.PathBase + request.Path, request.QueryString.Value) .Uri; // check addressing version none requirements if (message.Version.Addressing == AddressingVersion.None) { try { if (message.Headers.Action != null) { throw new ProtocolException("Action present when not expected."); } if (message.Headers.To != null) { throw new ProtocolException("To present when not expected."); } } catch (XmlException) { // handled } catch (CommunicationException) { // handled } // override message to with ASP.Net core URI message.Headers.To = AspNetCoreUri.GetUri(request.HttpContext); } // derive SOAP action var action = ReadSoapAction(request, message); if (action != null) { action = WebUtility.UrlDecode(action); if (action.Length >= 2 && action[0] == '"' && action[action.Length - 1] == '"') { action = action.Substring(1, action.Length - 2); } if (message.Version.Addressing == AddressingVersion.None) { message.Headers.Action = action; } // check that action isn't mismatched if (action.Length > 0 && string.Compare(message.Headers.Action, action, StringComparison.Ordinal) != 0) { throw new ProtocolException($"Mismatched action: '{message.Headers.Action}' != '{action}'"); } } }