コード例 #1
0
        public void ProcessRequest(HttpContext context)
        {
            string urlPath = context.Request.AppRelativeCurrentExecutionFilePath.Substring("~/api/".Length) + context.Request.PathInfo;


            /*
             *
             */
            JsonRequest request = new JsonRequest();

            request.ExecutionId = Guid.NewGuid();
            request.Rule        = urlPath.Replace("/", ".");
            request.MomentStart = DateTime.UtcNow;



            /*
             *
             */
            using (var sr = new StreamReader(HttpContext.Current.Request.InputStream))
            {
                sr.BaseStream.Seek(0, SeekOrigin.Begin);
                request.Message = sr.ReadToEnd();
            }


            /*
             *
             */
            RuleRunner rr   = new RuleRunner();
            IRule      rule = rr.Get(request.Rule);

            if (rule == null)
            {
                context.Response.StatusCode = 404;
                context.Response.End();
            }


            /*
             *
             */
            object oreq = JsonConvert.DeserializeObject(request.Message, rule.RequestType);


            /*
             *
             */
            JsonResponse response;

            try
            {
                object oresp = rr.Run(rule, oreq);

                response         = new JsonResponse();
                response.IsFault = false;
                response.Message = JsonConvert.SerializeObject(oresp);
            }
            catch (ActorException)
            {
                // TODO
                response         = new JsonResponse();
                response.IsFault = false;
                response.Message = "{}";
            }
            catch (Exception)
            {
                // TODO
                response         = new JsonResponse();
                response.IsFault = true;
                response.Message = "{}";
            }


            /*
             *
             */
            context.Response.TrySkipIisCustomErrors = true;
            context.Response.StatusCode             = 200;
            context.Response.CacheControl           = "private";
            context.Response.ContentType            = "application/json; charset=utf-8";

            context.Response.Headers.Add("X-Hafnium-ExecutionId", request.ExecutionId.ToString("D"));
            context.Response.Headers.Add("X-Hafnium-MomentStart", request.MomentStart.ToString("s"));
            context.Response.Headers.Add("X-Hafnium-MomentEnd", DateTime.UtcNow.ToString("s"));

            context.Response.Write(response.Message);
            context.Response.End();
        }
コード例 #2
0
        public void ProcessRequest(HttpContext context)
        {
            #region Validations

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            #endregion


            /*
             *
             */
            ExecutionHeader execution = new ExecutionHeader();
            execution.ExecutionId = Guid.NewGuid();
            execution.MomentStart = DateTime.UtcNow;


            /*
             *
             */
            SoapRequest request = null;

            if (context.Request.Headers["SOAPAction"] != null)
            {
                request            = new SoapRequest();
                request.Version    = SoapVersion.Soap11;
                request.SoapAction = context.Request.Headers["SOAPAction"];
                request.SoapAction = request.SoapAction.Substring(1, request.SoapAction.Length - 2);
            }
            else
            {
                var values = context.Request.ContentType
                             .Split(';')
                             .Select(s =>
                {
                    var p = s.Split(new char[] { '=' }, 2);

                    if (p.Length == 1)
                    {
                        return new { Key = "content-type", Value = p[0] }
                    }
                    ;
                    else
                    {
                        return new { Key = p[0], Value = p[1] }
                    };
                }).ToList();

                var contentType = values.FirstOrDefault(x => x.Key == "content-type");
                var action      = values.FirstOrDefault(x => x.Key == "action");

                if (contentType?.Value == "application/soap+xml" && action != null)
                {
                    request            = new SoapRequest();
                    request.Version    = SoapVersion.Soap12;
                    request.SoapAction = action.Value.Substring(1, action.Value.Length - 2);
                }
            }

            if (request == null)
            {
                ActorException error = new WebException(ER.Soap_RequestNotSoap);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }


            /*
             * Derive the rule being invoked, based on the URL of the request.
             */
            if (request.SoapAction.StartsWith(WebServicesConfiguration.Current.Namespace) == false)
            {
                ActorException error = new WebException(ER.Soap_ActionUnsupported, request.SoapAction, WebServicesConfiguration.Current.Namespace);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }

            string ruleName = request.SoapAction.Substring(WebServicesConfiguration.Current.Namespace.Length).Replace("/", ".");


            /*
             *
             */
            using (var sr = new StreamReader(HttpContext.Current.Request.InputStream))
            {
                sr.BaseStream.Seek(0, SeekOrigin.Begin);
                request.Message = sr.ReadToEnd();
            }


            /*
             * Service NS - derived from the name of the rule :)
             */
            string[] parts     = ruleName.Split('.');
            string   serviceNs = string.Join("/", parts.Take(parts.Length - 2)) + "/";


            /*
             *
             */
            RuleRunner rr   = new RuleRunner();
            IRule      rule = rr.Get(ruleName);

            if (rule == null)
            {
                ActorException error = new WebException(ER.Soap_ActionUnknown, request.SoapAction);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }


            /*
             *
             */
            XNamespace soapNs;

            if (request.Version == SoapVersion.Soap11)
            {
                soapNs = "http://schemas.xmlsoap.org/soap/envelope/";
            }
            else
            {
                soapNs = "http://www.w3.org/2003/05/soap-envelope";
            }

            XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
            manager.AddNamespace("soap", soapNs.NamespaceName);


            /*
             *
             */
            XDocument requestDoc;

            try
            {
                using (StringReader sr = new StringReader(request.Message))
                {
                    requestDoc = XDocument.Load(sr);
                }
            }
            catch (XmlException ex)
            {
                ActorException error = new WebException(ER.Soap_RequestNotXml, ex);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }

            XElement element = requestDoc.XPathSelectElement(" /soap:Envelope/soap:Body/*[ 1 ] ", manager);

            if (element == null)
            {
                ActorException error = new WebException(ER.Soap_BodyNotFound);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }


            /*
             *
             */
            object        oreq;
            XmlSerializer der = XmlSerializerFor(rule.RequestType, serviceNs);

            try
            {
                oreq = der.Deserialize(element.CreateReader());
            }
            catch (InvalidOperationException ex)
            {
                ActorException error = new WebException(ER.Soap_RequestInvalid, ex, rule.Name, rule.RequestType.FullName);

                var fault = ToFault(request.Version, execution, error);
                ResponseEmit(context, fault);
                return;
            }


            /*
             *
             */
            SoapResponse response;

            try
            {
                object oresp;

                oresp = rr.Run(rule, oreq);

                response = ToResponse(request.Version, execution, oresp, serviceNs);
            }
            catch (ActorException ex)
            {
                response = ToFault(request.Version, execution, ex);
            }
            catch (Exception ex)
            {
                ActorException aex = new WebException(ER.Soap_UnhandledException, ex);

                response = ToFault(request.Version, execution, aex);
            }


            /*
             *
             */
            ResponseEmit(context, response);
            return;
        }