Пример #1
0
        private async Task FireOnResponseCompleted(ServiceMessage msg)
        {
            var onCompleted = msg._onCompleted;

            if (onCompleted != null)
            {
                foreach (var entry in onCompleted)
                {
                    try
                    {
                        await entry.Key.Invoke(entry.Value);
                    }
                    catch (Exception ex)
                    {
                        ReportApplicationError(msg, ex);
                    }
                }
            }
        }
Пример #2
0
        private async Task FireOnResponseStarting(ServiceMessage msg)
        {
            var onStarting = msg._onStarting;

            if (onStarting != null)
            {
                try
                {
                    foreach (var entry in onStarting)
                    {
                        await entry.Key.Invoke(entry.Value);
                    }
                }
                catch (Exception ex)
                {
                    ReportApplicationError(msg, ex);
                }
            }
        }
Пример #3
0
        internal static HttpResponsePacket ToHttpResponsePacket(this ServiceMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var response = new HttpResponsePacket();

            var respFeature = message as IHttpResponseFeature;

            if (respFeature.Headers != null)
            {
                foreach (var hdr in respFeature.Headers)
                {
                    response.Headers.Add(hdr.Key, hdr.Value);
                }
            }

            response.Version    = HTTP_RESPONSE_VERSION;
            response.StatusCode = respFeature.StatusCode;
            if (String.IsNullOrEmpty(respFeature.ReasonPhrase))
            {
                response.StatusDescription = ReasonPhrases.ToReasonPhrase(response.StatusCode) ?? "Unknown";
            }
            else
            {
                response.StatusDescription = respFeature.ReasonPhrase;
            }

            if (message.OriginalResponseBody != null && message.OriginalResponseBody.CanRead)
            {
                //NOTE: OriginalResponseBody.CanRead will be false if the stream was disposed.

                response.Content = message.OriginalResponseBody.ToArray();
            }

            //Add/Update Server header
            response.Headers["Server"] = HTTP_RESPONSE_SERVER_HEADER;

            return(response);
        }
Пример #4
0
        internal static bool TryGetServiceMessage(this HttpRequestPacket request, out ServiceMessage message)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            message = new ServiceMessage();

            //Build Request
            IHttpRequestFeature req = message as IHttpRequestFeature;

            Uri uri;

            try
            {
                uri = request.BuildUri(null, null);
            }
            catch
            {
                message = null;
                return(false);
            }
            req.Path = uri.AbsolutePath;

            req.Protocol    = "HTTP/" + request.Version;
            req.QueryString = uri.Query;
            req.Method      = request.Method;

            if (request.Content != null && request.Content.Length > 0)
            {
                message.CreateRequestBody(request.Content);
            }

            //Add Request Headers
            {
                var headers = new HeaderDictionary();

                foreach (var hdr in request.Headers)
                {
                    if (hdr.Key != null && hdr.Key.Trim().ToUpperInvariant() == "CONTENT-LENGTH")
                    {
                        continue;                                                                           // Content-length is calculated based on actual content.
                    }
                    //NOTE: Client already folds Request Headers into RequestPacket, so there's no need to fold it again here.
                    headers.Add(hdr.Key, hdr.Value.ToArray());
                }

                if (message.OriginalRequestBody != null)
                {
                    headers.Add("Content-Length", request.Content.Length.ToString());
                }
                req.Headers = headers;
            }


            //Create Response
            message.CreateResponseBody();
            IHttpResponseFeature resp = message as IHttpResponseFeature;

            resp.StatusCode = 200;

            //Add Response Headers
            {
                var headers = new HeaderDictionary();

                headers.Add("Server", HTTP_RESPONSE_SERVER_HEADER[0]);
                resp.Headers = headers;
            }

            return(true);
        }
Пример #5
0
 private void ReportApplicationError(ServiceMessage msg, Exception ex)
 {
     msg._applicationException = ex;
     //TODO: Log Application error
 }
Пример #6
0
        /// <summary>
        /// Processes a request.
        /// </summary>
        private async Task ProcessRequest(MessageContext restbusContext, CancellationToken cancellationToken)
        {
            //NOTE: This method is called on a background thread and must be protected by an outer big-try catch

            TContext       context      = default(TContext);
            Exception      appException = null;
            ServiceMessage msg          = null;
            bool           appInvoked   = false;

            try
            {
                if (disposed)
                {
                    msg = CreateResponse(HttpStatusCode.ServiceUnavailable, "The server is no longer available.");
                }
                else
                {
                    if (!restbusContext.Request.TryGetServiceMessage(out msg))
                    {
                        //Bad message
                        msg = CreateResponse(HttpStatusCode.BadRequest, "Bad Request");
                    }
                    else
                    {
                        context = application.CreateContext(msg);

                        //Call application
                        appInvoked = true;
                        try
                        {
                            await application.ProcessRequestAsync(context).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            ReportApplicationError(msg, ex);
                        }
                        finally
                        {
                            //Call FireOnResponseStarting if message didn't encounter an exception.
                            if (!msg.HasApplicationException)
                            {
                                await FireOnResponseStarting(msg).ConfigureAwait(false);
                            }
                        }
                    }
                }

                if (msg.HasApplicationException)
                {
                    appException = msg._applicationException;

                    //If request encountered an exception then return an Internal Server Error (with empty body) response.
                    msg.Dispose();
                    msg = CreateResponse(HttpStatusCode.InternalServerError, null);
                }


                //Send Response
                HttpResponsePacket responsePkt;

                try
                {
                    responsePkt = msg.ToHttpResponsePacket();
                }
                catch (Exception ex)
                {
                    responsePkt = CreateResponseFromException(ex).ToHttpResponsePacket();
                }

                try
                {
                    subscriber.SendResponse(restbusContext, responsePkt);
                }
                catch
                {
                    //TODO: Log SendResponse error
                }

                //Call OnCompleted callbacks
                if (appInvoked)
                {
                    await FireOnResponseCompleted(msg).ConfigureAwait(false);
                }
            }
            finally
            {
                if (appInvoked)
                {
                    application.DisposeContext(context, appException);
                }

                if (msg != null)
                {
                    msg.Dispose();
                }
            }
        }