Example #1
0
 protected virtual void OnRequestReceived(HttpServerEventArgs <TContext> e)
 {
     RequestReceived?.Invoke(this, e);
 }
Example #2
0
        protected virtual void HandleRequest(TContext context)
        {
            var httpMethod = RequestHttpMethodFromContext(context);
            var realUrl    = RequestUriFromContext(context);
            var availableMethodsForPath = new List <string>();
            var path = realUrl.AbsolutePath;

            // strip multiple slashes
            while (path.StartsWith("//"))
            {
                path = path.Substring(1);
            }

            var lea = new HttpServerEventArgs <TContext>(context);

            OnRequestReceived(lea);
            if (lea.Responded)
            {
                return;
            }

            // find a handler
            foreach (var handler in Handlers)
            {
                Match match = handler.Matcher.Match(path);
                if (!match.Success)
                {
                    continue;
                }

                // we found a match
                var argumentStrings = new Dictionary <string, string>();
                foreach (string groupName in handler.ParameterNames)
                {
                    argumentStrings[groupName] = match.Groups[groupName].Value;
                }

                ParameterInfo[] parameters = handler.Endpoint.GetParameters();
                // this has been verified during adding
                Debug.Assert(parameters.Length > 0);
                Debug.Assert(parameters[0].ParameterType == typeof(TContext));

                // add the context as the first argument value
                var argValues = new List <object> {
                    context
                };

                var failed = false;
                foreach (ParameterInfo argument in parameters.Skip(1))
                {
                    if (!handler.ParameterNames.Contains(argument.Name))
                    {
                        // this has been verified during adding
                        Debug.Assert(argument.HasDefaultValue);

                        argValues.Add(argument.DefaultValue);
                        continue;
                    }

                    string str = HttpDispatcherUtil.UrlDecodeUtf8(argumentStrings[argument.Name]);

                    var e = new ParseValueEventArgs <TContext>(context, handler.Responder, handler.Endpoint,
                                                               argument.Name, argument.ParameterType, str);
                    OnParseValue(e);
                    if (e.Responded)
                    {
                        return;
                    }

                    if (e.Parsed)
                    {
                        argValues.Add(str);
                        continue;
                    }

                    // some defaults
                    if (argument.ParameterType == typeof(string))
                    {
                        argValues.Add(str);
                    }
                    else if (argument.ParameterType == typeof(int) ||
                             argument.ParameterType == typeof(int?))
                    {
                        int?value = HttpDispatcherUtil.ParseIntOrNull(str);
                        if (!value.HasValue)
                        {
                            failed = true;
                            break;
                        }
                        argValues.Add(value.Value);
                    }
                    else if (argument.ParameterType == typeof(long) ||
                             argument.ParameterType == typeof(long?))
                    {
                        long?value = HttpDispatcherUtil.ParseLongOrNull(str);
                        if (!value.HasValue)
                        {
                            failed = true;
                            break;
                        }
                        argValues.Add(value.Value);
                    }
                    else if (argument.ParameterType == typeof(float) ||
                             argument.ParameterType == typeof(float?))
                    {
                        double?value = HttpDispatcherUtil.ParseFloatOrNull(str);
                        if (!value.HasValue)
                        {
                            failed = true;
                            break;
                        }
                        argValues.Add((float)value.Value);
                    }
                    else if (argument.ParameterType == typeof(double) ||
                             argument.ParameterType == typeof(double?))
                    {
                        double?value = HttpDispatcherUtil.ParseDoubleOrNull(str);
                        if (!value.HasValue)
                        {
                            failed = true;
                            break;
                        }
                        argValues.Add(value.Value);
                    }
                    else if (argument.ParameterType == typeof(decimal) ||
                             argument.ParameterType == typeof(decimal?))
                    {
                        decimal?value = HttpDispatcherUtil.ParseDecimalOrNull(str);
                        if (!value.HasValue)
                        {
                            failed = true;
                            break;
                        }
                        argValues.Add(value.Value);
                    }
                    else
                    {
                        throw new ArgumentException($"don't know how to parse arguments of type {argument.ParameterType} after encountering argument {argument.Name} of {handler.Endpoint}");
                    }
                }

                if (failed)
                {
                    // unmatched argument; try next matcher
                    continue;
                }

                if (handler.EndpointAttribute.Method != null && handler.EndpointAttribute.Method != httpMethod)
                {
                    // endpoint's HTTP method doesn't match request's HTTP method
                    availableMethodsForPath.Add(handler.EndpointAttribute.Method);
                    continue;
                }

                // we're ready; dispatch it
                var eea = new EndpointEventArgs <TContext>(context, handler.Responder, handler.Endpoint);
                OnCallingEndpoint(eea);
                if (eea.Responded)
                {
                    return;
                }

                try
                {
                    handler.Endpoint.Invoke(handler.Responder, argValues.ToArray());
                }
                catch (TargetInvocationException exc)
                {
                    var reea = new ResponderExceptionEventArgs <TContext>(context, handler.Responder, handler.Endpoint,
                                                                          exc.InnerException);
                    OnResponderException(reea);
                    if (reea.Responded)
                    {
                        return;
                    }
                    SendJson500Exception(context, exc);
                }
                return;
            }

            // call the unhandled request handler
            var urea = new UnhandledRequestEventArgs <TContext>(context)
            {
                AvailableMethodsForPath = availableMethodsForPath
            };

            OnUnhandledRequest(urea);
            if (urea.Responded)
            {
                return;
            }

            // call the default unhandled request handler
            SendJson404(context);
        }