public void FindPathTemplates(string url, string key)
        {
            var table = new UriTemplateTable();  // Shorter paths and literal path segments should be added to the table first.
            table.Add("root", new UriTemplate("/"));
            table.Add("foo", new UriTemplate("/foo/{bar}"));
            table.Add("kit", new UriTemplate("/baz/kit"));
            table.Add("baz", new UriTemplate("/baz/{bar}"));
            table.Add("blob", new UriTemplate("/baz/{bar}/blob"));
            table.Add("goo", new UriTemplate("/{goo}/{bar}/blob"));


            var result = table.Match(new Uri(url, UriKind.RelativeOrAbsolute));

            if (string.IsNullOrEmpty(key))
            {
                Assert.Null(result);
            }
            else
            {
                Assert.Equal(key, result.Key);
            }

            Assert.NotNull(table["goo"]);
            Assert.Null(table["goo1"]);
        }
 public void out_of_two_templates_with_one_query_parameter_only_the_correct_one_is_used()
 {
     var table = new UriTemplateTable(new Uri("http://localhost"), new List<KeyValuePair<UriTemplate, object>>
     {
         new KeyValuePair<UriTemplate, object>(new UriTemplate("resource1?query={queryText}"), null),
         new KeyValuePair<UriTemplate, object>(new UriTemplate("resource1?query2={queryText}"), null)
     });
     Collection<UriTemplateMatch> match = table.Match(new Uri("http://localhost/resource1?query=testing a query"));
     match.Count.ShouldBe(1);
     match[0].QueryParameters["queryText"].ShouldBe("testing a query");
 }
예제 #3
0
        public void equidistant_matches_are_ordered_by_bound_params()
        {
            var table = new UriTemplateTable(new Uri("http://localhost"), new List <KeyValuePair <UriTemplate, object> >
            {
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1/{resourceId}"), null),
                new KeyValuePair <UriTemplate, object>(
                    new UriTemplate("resource1/{resourceId}?query={queryText}&query2={queryiestText}"), null),
            });

            var match =
                table.Match(new Uri("http://localhost/resource1/123?query=ceci_nest_pas_un_value"));

            match.Count.ShouldBe(2);
            match.First().QueryStringVariables.Count.ShouldBe(1);
            match.First().PathSegmentVariables.Count.ShouldBe(1);
            match.First().QueryParameters.Count.ShouldBe(2);
        }
        public void a_template_with_one_param_is_the_best_match_for_a_uri_with_one_param()
        {
            var table = new UriTemplateTable(new Uri("http://localhost"), new List <KeyValuePair <UriTemplate, object> >
            {
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1?query={queryText}&query2={queryiestText}"),
                                                       null),
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1"), null),
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1?query={quasiText}"), null)
            });
            Collection <UriTemplateMatch> match =
                table.Match(new Uri("http://localhost/resource1?query=ceci_nest_pas_un_value"));

            match.Count.ShouldBe(3);
            match[0].QueryStringVariables.Count.ShouldBe(1);
            match[0].QueryParameters.Count.ShouldBe(1);
            match[0].QueryStringVariables["quasiText"].ShouldBe("ceci_nest_pas_un_value");
        }
예제 #5
0
        static ThemeService()
        {
#if NETCOREAPP
            _templateTable = new UriTemplateTable();
            _templateTable.Add("theme", new UriTemplate(_baseUrl + _themeUrl));
            _templateTable.Add("accent", new UriTemplate(_baseUrl + _accentUrl));
            _templateTable.Add("uwptheme", new UriTemplate(_baseUrl + _uwpThemeUrl));
            _templateTable.Add("uwpaccent", new UriTemplate(_baseUrl + _uwpAccentUrl));
            _templateTable.Add("style", new UriTemplate(_baseUrl + _styleUrl));
#else
            _templateTable = new UriTemplateTable(_templateBaseUri);
            _templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(_themeTemplate, "theme"));
            _templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(_accentTemplate, "accent"));
            _templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(_uwpThemeTemplate, "uwptheme"));
            _templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(_uwpAccentTemplate, "uwpaccent"));
            _templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(_styleTemplate, "style"));
            _templateTable.MakeReadOnly(false);
#endif
        }
예제 #6
0
        public void irrelevant_params_do_not_affect_the_ordering()
        {
            var table = new UriTemplateTable(new Uri("http://localhost"), new List <KeyValuePair <UriTemplate, object> >
            {
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1?query={queryText}&query2={queryiestText}"),
                                                       null),
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1?query={queryText}&query3={queryiestText}"),
                                                       null),
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1"), null),
                new KeyValuePair <UriTemplate, object>(new UriTemplate("resource1?query={quasiText}"), null)
            });
            var match =
                table.Match(new Uri("http://localhost/resource1?query=ceci_nest_pas_un_value&irrelevant=value"));

            match.Count.ShouldBe(4);
            match[0].QueryStringVariables.Count.ShouldBe(1);
            match[0].QueryParameters.Count.ShouldBe(1);
            match[0].QueryStringVariables["quasiText"].ShouldBe("ceci_nest_pas_un_value");
        }
        private static bool CanUriMatch(UriTemplateTable methodSpecificTable, Uri requestUri, out string operationName)
        {
            Fx.Assert(requestUri != null, "The 'requestUri' parameter should not be null.");

            operationName = null;

            if (methodSpecificTable != null)
            {
                UriTemplateMatch result = methodSpecificTable.MatchSingle(requestUri);
                if (result != null)
                {
                    operationName = result.Data as string;
                    Fx.Assert(operationName != null, "The 'operationName' variable should never be null.");
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        public ContractRouter(Stream contractStream)
        {
            // By default, assume it is an OpenAPI contract
            // We can add another ctor that has a media type parameter to support
            // other contracts.

            var openApiDoc = new OpenApiDocument();

            JsonStreamingParser.ParseStream(contractStream, openApiDoc, OpenApiVocab.Create());

            _UriTemplateTable = new UriTemplateTable();
            foreach (var path in openApiDoc.Paths)
            {
                if (!string.IsNullOrWhiteSpace(path.Value.XController))
                {
                    _UriTemplateTable.Add(path.Value.XController.ToLowerInvariant(), new UriTemplate(path.Key));
                }
            }
        }
예제 #9
0
        public WebHttpOperationSelector(ServiceEndpoint endpoint)
        {
            this.UriTemplateTables = new Dictionary <string, UriTemplateTable>();
            Uri baseAddress = endpoint.Address.Uri;

            foreach (var operation in endpoint.Contract.Operations)
            {
                WebGetAttribute    webGet    = operation.Behaviors.Find <WebGetAttribute>();
                WebInvokeAttribute webInvoke = operation.Behaviors.Find <WebInvokeAttribute>();
                string             method    = (null != webGet) ? "GET" : webInvoke.Method;
                UriTemplateTable   uriTemplateTable;
                if (!this.UriTemplateTables.TryGetValue(method, out uriTemplateTable))
                {
                    uriTemplateTable = new UriTemplateTable(baseAddress);
                    this.UriTemplateTables.Add(method, uriTemplateTable);
                }
                string template = (null != webGet)?webGet.UriTemplate:webInvoke.UriTemplate;
                uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(template), operation.Name));
            }
        }
        /// <summary>
        /// The locate http receive activities.
        /// </summary>
        /// <param name="activity">
        /// The activity.
        /// </param>
        /// <param name="uriTemplateTable">
        /// The uri template table.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The activity is null
        /// </exception>
        private void LocateHttpReceiveActivities(Activity activity, UriTemplateTable uriTemplateTable)
        {
            if (activity == null)
            {
                throw new ArgumentNullException("activity");
            }

            if (activity is HttpReceive)
            {
                var receive = (HttpReceive)activity;

                uriTemplateTable.KeyValuePairs.Add(
                    new KeyValuePair <UriTemplate, object>(new UriTemplate(receive.UriTemplate), receive));
            }

            foreach (var childActivity in WorkflowInspectionServices.GetActivities(activity))
            {
                this.LocateHttpReceiveActivities(childActivity, uriTemplateTable);
            }
        }
예제 #11
0
        private void ConstructDispatcherTables(Uri prefix)
        {
            this.getDispatcherTable    = new UriTemplateTable(prefix);
            this.postDispatcherTable   = new UriTemplateTable(prefix);
            this.deleteDispatcherTable = new UriTemplateTable(prefix);

            var fields = typeof(DriverCommand).GetFields(BindingFlags.Public | BindingFlags.Static);

            foreach (var field in fields)
            {
                var commandName        = field.GetValue(null).ToString();
                var commandInformation = this.commandDictionary[commandName];
                var commandUriTemplate = new UriTemplate(commandInformation.ResourcePath);
                var templateTable      = this.FindDispatcherTable(commandInformation.Method);
                templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(commandUriTemplate, commandName));
            }

            this.getDispatcherTable.MakeReadOnly(false);
            this.postDispatcherTable.MakeReadOnly(false);
            this.deleteDispatcherTable.MakeReadOnly(false);
        }
예제 #12
0
        private UriTemplateTable FindDispatcherTable(string httpMethod)
        {
            UriTemplateTable tableToReturn = null;

            switch (httpMethod)
            {
            case CommandInfo.GetCommand:
                tableToReturn = this.getDispatcherTable;
                break;

            case CommandInfo.PostCommand:
                tableToReturn = this.postDispatcherTable;
                break;

            case CommandInfo.DeleteCommand:
                tableToReturn = this.deleteDispatcherTable;
                break;
            }

            return(tableToReturn);
        }
        public void FindTemplatesInGamesApi(string url, string key)
        {
            var table = new UriTemplateTable();
            table.Add("games", new UriTemplate("/games"));
            table.Add("gamessetup", new UriTemplate("/games/{gametitle}/Setup/{gamesid}"));
            table.Add("resource", new UriTemplate("/games/{gametitle}/Resources/{resourcetype}/{resourceid}"));
            table.Add("chat", new UriTemplate("/games/{gametitle}/{gameid}/Chat/{chatid}"));
            table.Add("state", new UriTemplate("/games/{gametitle}/{gameid}/State/{stateid}"));


            var result = table.Match(new Uri(url, UriKind.RelativeOrAbsolute));

            if (string.IsNullOrEmpty(key))
            {
                Assert.Null(result);
            }
            else
            {
                Assert.Equal(key, result.Key);
            }
        }
        public WebHttpDispatchOperationSelector(ServiceEndpoint endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }
            if (endpoint.Address == null)
            {
                throw new InvalidOperationException("EndpointAddress must be set in the argument ServiceEndpoint");
            }

            table = new UriTemplateTable(endpoint.Address.Uri);

            foreach (OperationDescription od in endpoint.Contract.Operations)
            {
                WebAttributeInfo info = od.GetWebAttributeInfo();
                if (info != null)
                {
                    table.KeyValuePairs.Add(new TemplateTablePair(info.BuildUriTemplate(od, null), od));
                }
            }
        }
예제 #15
0
        private void ConstructDispatcherTables(string prefix)
        {
            this.getDispatcherTable    = new UriTemplateTable(new Uri(prefix.Replace("*", "localhost")));
            this.postDispatcherTable   = new UriTemplateTable(new Uri(prefix.Replace("*", "localhost")));
            this.deleteDispatcherTable = new UriTemplateTable(new Uri(prefix.Replace("*", "localhost")));

            // DriverCommand is a static class with static fields containing the command names.
            // Since this is initialization code only, we'll take the perf hit in using reflection.
            FieldInfo[] fields = typeof(DriverCommand).GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo field in fields)
            {
                string           commandName        = field.GetValue(null).ToString();
                CommandInfo      commandInformation = CommandInfoRepository.Instance.GetCommandInfo(commandName);
                UriTemplate      commandUriTemplate = new UriTemplate(commandInformation.ResourcePath);
                UriTemplateTable templateTable      = this.FindDispatcherTable(commandInformation.Method);
                templateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(commandUriTemplate, commandName));
            }

            this.getDispatcherTable.MakeReadOnly(false);
            this.postDispatcherTable.MakeReadOnly(false);
            this.deleteDispatcherTable.MakeReadOnly(false);
        }
예제 #16
0
        public void FindTemplatesWithQueryStrings(string url, string key)
        {
            var table = new UriTemplateTable();   // More restrictive templates should have priority over less restrictive ones

            table.Add("fooxy3", new UriTemplate("/foo?x={x}&y={y}"));
            table.Add("fooxy2", new UriTemplate("/foo?x={x}{&y}"));
            table.Add("fooxy4", new UriTemplate("/foo?x={x}{&z}"));
            table.Add("fooxy", new UriTemplate("/foo{?x,y}"));
            table.Add("foo", new UriTemplate("/foo"));


            var result = table.Match(new Uri(url, UriKind.RelativeOrAbsolute));

            if (string.IsNullOrEmpty(key))
            {
                Assert.Null(result);
            }
            else
            {
                Assert.Equal(key, result.Key);
            }
        }
예제 #17
0
        public void FindTemplatesInGamesApi(string url, string key)
        {
            var table = new UriTemplateTable();

            table.Add("games", new UriTemplate("/games"));
            table.Add("gamessetup", new UriTemplate("/games/{gametitle}/Setup/{gamesid}"));
            table.Add("resource", new UriTemplate("/games/{gametitle}/Resources/{resourcetype}/{resourceid}"));
            table.Add("chat", new UriTemplate("/games/{gametitle}/{gameid}/Chat/{chatid}"));
            table.Add("state", new UriTemplate("/games/{gametitle}/{gameid}/State/{stateid}"));


            var result = table.Match(new Uri(url, UriKind.RelativeOrAbsolute));

            if (string.IsNullOrEmpty(key))
            {
                Assert.Null(result);
            }
            else
            {
                Assert.Equal(key, result.Key);
            }
        }
예제 #18
0
        public static void Snippet9()
        {
            // <Snippet9>
            Uri prefix = new Uri("http://localhost/");

            //Create a series of templates
            UriTemplate weatherByCity    = new UriTemplate("weather/ state}/ city}");
            UriTemplate weatherByCountry = new UriTemplate("weather/ country}/ village}");
            UriTemplate weatherByState   = new UriTemplate("weather/ state}");
            UriTemplate traffic          = new UriTemplate("traffic/*");
            UriTemplate wildcard         = new UriTemplate("*");

            //Create a template table
            UriTemplateTable table = new UriTemplateTable(prefix);

            //Add each template to the table with some associated data
            table.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(weatherByCity, "weatherByCity"));
            table.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(weatherByCountry, "weatherByCountry"));
            table.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(weatherByState, "weatherByState"));
            table.KeyValuePairs.Add(new KeyValuePair <UriTemplate, Object>(traffic, "traffic"));

            table.MakeReadOnly(true);

            //Call Match to retrieve some match results:
            ICollection <UriTemplateMatch> results = null;
            Uri weatherInSeattle = new Uri("http://localhost/weather/Washington/Seattle");

            results = table.Match(weatherInSeattle);
            if (results != null)
            {
                Console.WriteLine("Matching templates:");
                foreach (UriTemplateMatch match in results)
                {
                    Console.WriteLine("    0}", match.Template);
                }
            }
            // </Snippet9>
        }
        UriTemplate FindBestMatchingTemplate(UriTemplateTable templates,
                                             object resourceKey,
                                             string uriName,
                                             NameValueCollection keyValues)
        {
            resourceKey = EnsureIsNotType(resourceKey);
            var matchingTemplates =
                from template in templates.KeyValuePairs
                let descriptor = (UrlDescriptor)template.Value
                                 where CompatibleKeys(resourceKey, descriptor.ResourceKey)
                                 where UriNameMatches(uriName, descriptor.UriName)
                                 let templateParameters =
                    template.Key.PathSegmentVariableNames.Concat(template.Key.QueryStringVariableNames).ToList()
                    let hasKeys = keyValues != null && keyValues.HasKeys()
                                  where (templateParameters.Count == 0) ||
                                  (templateParameters.Count > 0 &&
                                   hasKeys &&
                                   templateParameters.All(x => keyValues.AllKeys.Contains(x, StringComparison.OrdinalIgnoreCase)))
                                  orderby templateParameters.Count descending
                                  select template.Key;

            return(matchingTemplates.FirstOrDefault());
        }
 public void Clear()
 {
     _templates = new UriTemplateTable();
 }
        /// <summary>
        /// Create predicate function based on passed query parameters
        /// </summary>
        /// <param name="operationIds">Comma delimited list of operationIds or * for all operations.</param>
        /// <param name="tags">Comma delimited list of tags or a single regex.</param>
        /// <param name="url">Url path to match with Operation Ids.</param>
        /// <param name="graphVersion">Version of Microsoft Graph.</param>
        /// <param name="forceRefresh">Don't read from in-memory cache.</param>
        /// <returns>A predicate</returns>
        public static async Task <Func <OpenApiOperation, bool> > CreatePredicate(string operationIds, string tags, string url,
                                                                                  string graphVersion, bool forceRefresh)
        {
            if (operationIds != null && tags != null)
            {
                return(null); // Cannot filter by operationIds and tags at the same time
            }
            if (url != null && (operationIds != null || tags != null))
            {
                return(null); // Cannot filter by url and either 0perationIds and tags at the same time
            }

            Func <OpenApiOperation, bool> predicate;

            if (operationIds != null)
            {
                if (operationIds == "*")
                {
                    predicate = (o) => true;  // All operations
                }
                else
                {
                    var operationIdsArray = operationIds.Split(',');
                    predicate = (o) => operationIdsArray.Contains(o.OperationId);
                }
            }
            else if (tags != null)
            {
                var tagsArray = tags.Split(',');
                if (tagsArray.Length == 1)
                {
                    var regex = new Regex(tagsArray[0]);

                    predicate = (o) => o.Tags.Any(t => regex.IsMatch(t.Name));
                }
                else
                {
                    predicate = (o) => o.Tags.Any(t => tagsArray.Contains(t.Name));
                }
            }
            else if (url != null)
            {
                /* Extract the respective Operation Id(s) that match the provided url path */

                if (!_openApiOperationsTable.Any() || forceRefresh)
                {
                    _uriTemplateTable       = new UriTemplateTable();
                    _openApiOperationsTable = new Dictionary <int, OpenApiOperation[]>();

                    await PopulateReferenceTablesAync(graphVersion, forceRefresh);
                }

                url = url.Replace('-', '_');

                TemplateMatch resultMatch = _uriTemplateTable.Match(new Uri(url.ToLower(), UriKind.RelativeOrAbsolute));

                if (resultMatch == null)
                {
                    return(null);
                }

                /* Fetch the corresponding Operations Id(s) for the matched url */

                OpenApiOperation[] openApiOps        = _openApiOperationsTable[int.Parse(resultMatch.Key)];
                string[]           operationIdsArray = openApiOps.Select(x => x.OperationId).ToArray();

                predicate = (o) => operationIdsArray.Contains(o.OperationId);
            }
            else
            {
                predicate = null;
            }

            return(predicate);
        }
 public void Clear()
 {
     this.templates = new UriTemplateTable();
 }
예제 #23
0
        public static void Main()
        {
            Uri prefix = new Uri("http://localhost/");

            //One interesting use for UriTemplateTable is as a dispatching engine.
            //This is accomplished by using the UriTemplateTable to associate
            //a delegate handler with each UriTemplate.

            //To start, we need a UriTemplateTable.
            UriTemplateTable table = new UriTemplateTable(prefix);

            //Now, we add templates to the table and associate them
            //with handler functions, written as anonymous delegates:

            AddHandler(table, new UriTemplate("weather/{state}/{city}"),
                       delegate(UriTemplateMatch r)
            {
                Console.WriteLine("Matched the WeatherByCity template");
                Console.WriteLine("State: {0}", r.BoundVariables["state"]);
                Console.WriteLine("City: {0}", r.BoundVariables["city"]);
            });

            AddHandler(table, new UriTemplate("weather/{state}"),
                       delegate(UriTemplateMatch r)
            {
                Console.WriteLine("Matched the WeatherByState template");
                Console.WriteLine("State: {0}", r.BoundVariables["state"]);
            });

            AddHandler(table, new UriTemplate("traffic/*"),
                       delegate(UriTemplateMatch r)
            {
                Console.WriteLine("Matched the traffic/* template");
                Console.WriteLine("Wildcard segments:");

                foreach (string s in r.WildcardPathSegments)
                {
                    Console.WriteLine("   " + s);
                }
            });

            //MakeReadOnly() freezes the table and prevents further additions.
            //Passing false to this method will disallow duplicate URI's,
            //guaranteeing that at most a single match will be returned.
            //Calling this method explictly is optional, as the collection
            //will be made read-only during the first call to Match() or MatchSingle()
            table.MakeReadOnly(false);

            Uri request = null;

            //Match WeatherByCity
            request = new Uri("http://localhost/weather/Washington/Seattle");
            Console.WriteLine(request);
            InvokeDelegate(table.MatchSingle(request));

            //Match WeatherByState
            request = new Uri("http://localhost/weather/Washington");
            Console.WriteLine(request);
            InvokeDelegate(table.MatchSingle(request));

            //Wildcard match Traffic
            request = new Uri("http://localhost/Traffic/Washington/Seattle/SR520");
            Console.WriteLine(request);
            InvokeDelegate(table.MatchSingle(request));

            Console.WriteLine("Press any key to terminate");
            Console.ReadLine();
        }
        public static long Run()
        {
            long      ran        = 0;
            const int Iterations = 1000000; // 100 * 1000 * 1000;

            var baseUri = new Uri("http://x");
            var table   = new UriTemplateTable(
                baseUri,
                new[] { "devices/{deviceId}/messages/events/{*subTopic}", "devices/{deviceId}/messages/log/{level=info}/{subject=n%2Fa}" }.Select(x => new KeyValuePair <UriTemplate, object>(new UriTemplate(x, false), x)));

            table.MakeReadOnly(true);
            Regex[] regexes = new[] { "^devices/(?<deviceId>[^/]*)/messages/events/(?<subTopic>.*)$", "^devices/(?<deviceId>[^/]*)/messages/log(/(?<level>[^/]*)(/(?<level>[^/]*))?)?$" }.Select(x => new Regex(x, RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.CultureInvariant)).ToArray();

            var values = new[] { "devices/WAUCB28D7XA451194/messages/events/some/other/segments", "devices/WAUCB28D7XA451194/messages/log/warning/oilPressureAlert" };

            CodeTimer.Time(true, "table", Iterations, () =>
            {
                foreach (string value in values)
                {
                    Collection <UriTemplateMatch> matches = table.Match(new Uri(baseUri, value));
                    if (matches.Count == 0)
                    {
                        continue;
                    }
                    if (matches.Count > 1)
                    {
                        //
                    }
                    UriTemplateMatch match = matches[0];
                    string deviceId        = match.BoundVariables["deviceId"];
                    if (deviceId[0] == 'W')
                    {
                        unchecked
                        {
                            ran++;
                        }
                    }
                }
            });

            CodeTimer.Time(true, "regex", Iterations, () =>
            {
                foreach (string value in values)
                {
                    foreach (Regex regex in regexes)
                    {
                        Match match = regex.Match(value);
                        if (!match.Success)
                        {
                            continue;
                        }
                        string deviceId = match.Groups["deviceId"].Value;
                        if (deviceId[0] == 'W')
                        {
                            unchecked
                            {
                                ran++;
                            }
                        }
                        break;
                    }
                }
            });

            return(ran);
        }
예제 #25
0
        private ServerResponse DispatchRequest(Uri resourcePath, string httpMethod, string requestBody)
        {
            HttpStatusCode codeToReturn    = HttpStatusCode.OK;
            Response       commandResponse = new Response();
            Dictionary <string, string> locatorParameters = new Dictionary <string, string>();
            UriTemplateTable            templateTable     = this.FindDispatcherTable(httpMethod);
            UriTemplateMatch            match             = templateTable.MatchSingle(resourcePath);

            if (resourcePath.AbsolutePath.ToUpperInvariant().Contains(ShutdownUrlFragment))
            {
                this.serverLogger.Log("Executing: [Shutdown] at URL: " + resourcePath.AbsolutePath);
            }
            else if (match == null)
            {
                codeToReturn          = HttpStatusCode.NotFound;
                commandResponse.Value = "No command associated with " + resourcePath.AbsolutePath;
            }
            else
            {
                string    relativeUrl    = match.RequestUri.AbsoluteUri.Substring(match.RequestUri.AbsoluteUri.IndexOf(this.listenerPath, StringComparison.OrdinalIgnoreCase) + this.listenerPath.Length - 1);
                SessionId sessionIdValue = null;

                string commandName = (string)match.Data;
                foreach (string key in match.BoundVariables.Keys)
                {
                    string value = match.BoundVariables[key];
                    locatorParameters.Add(key, value);
                }

                Command commandToExecute = new Command(commandName, requestBody);

                object          resultValue = null;
                WebDriverResult resultCode  = WebDriverResult.Success;
                try
                {
                    CommandHandler handler = this.handlerFactory.CreateHandler(commandToExecute.Name, locatorParameters, commandToExecute.Parameters);
                    sessionIdValue = handler.SessionId;
                    this.serverLogger.Log("Executing: " + handler.ToString() + " at URL: " + relativeUrl);
                    resultValue  = handler.Execute();
                    codeToReturn = handler.StatusCode;
                }
                catch (CommandNotImplementedException ex)
                {
                    codeToReturn = HttpStatusCode.NotImplemented;
                    resultValue  = ex.Message + " (" + commandName + ")";
                }
                catch (InvalidCommandException ex)
                {
                    codeToReturn = HttpStatusCode.MethodNotAllowed;
                    resultValue  = ex.Message;
                }
                catch (ResourceNotFoundException ex)
                {
                    codeToReturn = HttpStatusCode.NotFound;
                    resultValue  = ex.Message + " (" + resourcePath.AbsolutePath + ")";
                }
                catch (InvalidParameterException ex)
                {
                    codeToReturn = HttpStatusCode.BadRequest;
                    resultValue  = ex.Message;
                }
                catch (NoSuchWindowException ex)
                {
                    resultCode  = WebDriverResult.NoSuchWindow;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (NoSuchElementException ex)
                {
                    resultCode  = WebDriverResult.NoSuchElement;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (NoSuchFrameException ex)
                {
                    resultCode  = WebDriverResult.NoSuchFrame;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (StaleElementReferenceException ex)
                {
                    resultCode  = WebDriverResult.ObsoleteElement;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (ElementNotVisibleException ex)
                {
                    resultCode  = WebDriverResult.ElementNotDisplayed;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (InvalidElementStateException ex)
                {
                    resultCode  = WebDriverResult.InvalidElementState;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (NotImplementedException ex)
                {
                    resultCode  = WebDriverResult.InvalidElementState;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (XPathLookupException ex)
                {
                    resultCode  = WebDriverResult.XPathLookupError;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (WebDriverTimeoutException ex)
                {
                    resultCode  = WebDriverResult.Timeout;
                    resultValue = CreateErrorResponse(commandName, ex);
                }
                catch (UnhandledAlertException ex)
                {
                    resultCode = WebDriverResult.UnexpectedAlertOpen;

                    // This is ridiculously ugly. To be refactored.
                    ErrorResponse err = CreateErrorResponse(commandName, ex);
                    Dictionary <string, object> resp = new Dictionary <string, object>();
                    resp["class"]      = err.ClassName;
                    resp["message"]    = err.Message;
                    resp["screen"]     = err.Screenshot;
                    resp["stackTrace"] = err.StackTrace;
                    Dictionary <string, object> alert = new Dictionary <string, object>();
                    alert["text"] = ex.Alert.Text;
                    resp["alert"] = alert;
                    resultValue   = resp;
                }
                catch (Exception ex)
                {
                    resultCode  = WebDriverResult.UnhandledError;
                    resultValue = CreateErrorResponse(commandName, ex);
                }

                commandResponse        = new Response(sessionIdValue);
                commandResponse.Status = resultCode;
                commandResponse.Value  = resultValue;

                this.serverLogger.Log("Done: " + relativeUrl);
            }

            return(new ServerResponse(commandResponse, codeToReturn));
        }
        private UriTemplate FindBestMatchingTemplate(UriTemplateTable templates, object resourceKey, string uriName, NameValueCollection keyValues)
        {
            resourceKey = this.EnsureIsNotType(resourceKey);

            var matchingTemplates =
                from template in templates.KeyValuePairs
                let descriptor = (UrlDescriptor)template.Value
                where CompatibleKeys(resourceKey, descriptor.ResourceKey)
                where UriNameMatches(uriName, descriptor.UriName)
                let templateParameters =
                    template.Key.PathSegmentVariableNames.Concat(template.Key.QueryValueVariableNames).ToList()
                let hasKeys = keyValues != null && keyValues.HasKeys()
                where (templateParameters.Count == 0) ||
                      (templateParameters.Count > 0
                       && hasKeys
                       && templateParameters.All(x => keyValues.AllKeys.Contains(x, StringComparison.OrdinalIgnoreCase)))
                orderby templateParameters.Count descending
                select template.Key;

            return matchingTemplates.FirstOrDefault();
        }
예제 #27
0
 private static void AddHandler(UriTemplateTable table, UriTemplate template, Handler handler)
 {
     table.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(template, handler));
 }
예제 #28
0
        /// <summary>
        /// Executes if the current request is processed by ASP.NET on the begin of request.
        /// Rewrites the Url if there IIS is configured for extensionless Urls.
        /// </summary>
        /// <param name="sender">The current <see cref="HttpApplication" />.</param>
        /// <param name="e">The EventArgs.</param>
        private void context_BeginRequest(object sender, EventArgs e)
        {
            // Get the current HTTP context.
            var context = ((HttpApplication)sender).Context;

            // Get the navigation service.
            var navigationService =
                this.Container.Resolve <INavigationService>();

            // Get the url from the current request.
            var currentPath = context.Request.Url;

            // Set up the table with the URI templates.
            var uriTemplateTable = new UriTemplateTable();

            // Set the table's base address.
            uriTemplateTable.BaseAddress = new Uri(navigationService.GetApplicationPath());

            // Set the rules.
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetDownloadUriTemplate() + "{data}"), HandlerAction.Download));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetRedirectUriTemplate() + "{data}"), HandlerAction.Redirect));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate()), HandlerAction.SecurityTokenService));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate().TrimEnd('/')), HandlerAction.SecurityTokenService));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate() + "{data}"), HandlerAction.SecurityTokenService));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate().TrimEnd('/')), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate()), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}"), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/"), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}"), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}/"), HandlerAction.UI));
            uriTemplateTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}/{data}"), HandlerAction.UI));

            // Check whether the current path matches any of these rewrite rules. If not, return.
            UriTemplateMatch uriTemplateMatch = uriTemplateTable.MatchSingle(currentPath);

            if (uriTemplateMatch == null)
            {
                // Before returning, check whether silkveil.net's application handler was called
                // directly. If so, check if SSL is required for silkveil.net, and redirect, if
                // neccessary.
                if (context.Request.Url.GetLeftPart(UriPartial.Path).TrimEnd('/').ToLowerInvariant() ==
                    navigationService.GetApplicationHandlerFactoryPath().TrimEnd('/').ToLowerInvariant())
                {
                    this.Container.Resolve <IProtocolManager>().RedirectIfNeccessary(context.Request);
                }

                // Return to the caller.
                return;
            }

            // Check if SSL is required for silkveil.net, and redirect, if neccessary.
            this.Container.Resolve <IProtocolManager>().RedirectIfNeccessary(context.Request);

            // Otherwise, redirect using the URI match.
            var applicationHandlerFactoryVirtualPath = navigationService.GetApplicationHandlerFactoryVirtualPath();

            switch ((HandlerAction)uriTemplateMatch.Data)
            {
            case HandlerAction.Download:
                context.RewritePath(string.Format(CultureInfo.InvariantCulture,
                                                  applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}", HandlerAction.Download, uriTemplateMatch.BoundVariables["data"]));
                break;

            case HandlerAction.Redirect:
                context.RewritePath(string.Format(CultureInfo.InvariantCulture,
                                                  applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}", HandlerAction.Redirect, uriTemplateMatch.BoundVariables["data"]));
                break;

            case HandlerAction.SecurityTokenService:
                string data = uriTemplateMatch.BoundVariables["data"] ?? "Logon";
                string wa;
                switch (data)
                {
                case "Logon":
                    wa = WSFederationConstants.Actions.SignIn;
                    break;

                case "Logoff":
                    wa = WSFederationConstants.Actions.SignOut;
                    break;

                default:
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture,
                                                                      "The data '{0}' is not supported.", data));
                }
                var wtrealm = "http://www.silkveil.net/";
                context.RewritePath(string.Format(CultureInfo.InvariantCulture,
                                                  applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}&wa={2}&wtrealm={3}", HandlerAction.SecurityTokenService,
                                                  data, wa, HttpUtility.UrlEncode(wtrealm)));
                break;

            case HandlerAction.UI:
                context.RewritePath(string.Format(CultureInfo.InvariantCulture,
                                                  applicationHandlerFactoryVirtualPath + "?Action={0}&Controller={1}&ControllerAction={2}&Data={3}", HandlerAction.UI,
                                                  uriTemplateMatch.BoundVariables["controller"] ?? string.Empty,
                                                  uriTemplateMatch.BoundVariables["controllerAction"] ?? string.Empty,
                                                  uriTemplateMatch.BoundVariables["data"] ?? string.Empty));
                break;
            }
        }
        public void FindTemplatesWithArrayQueryParameters()
        {
            var table = new UriTemplateTable();   // More restrictive templates should have priority over less restrictuve ones
            table.Add("fooxy3", new UriTemplate("/foo?x={x}&y={y}"));
            table.Add("fooxy2", new UriTemplate("/foo?x={x}{&y}"));
            table.Add("fooxy4", new UriTemplate("/foo?x={x}{&z}"));
            table.Add("fooxy", new UriTemplate("/foo{?x,y}"));
            table.Add("foo", new UriTemplate("/foo"));


            var result = table.Match(new Uri("/foo?x=a,b,c,d", UriKind.RelativeOrAbsolute));

            Assert.Equal("fooxy2", result.Key);
            
        }
        protected virtual string SelectOperation(ref Message message, out bool uriMatched)
        {
            if (message == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
            }
            uriMatched = false;
            if (this.methodSpecificTables == null)
            {
                return(this.catchAllOperationName);
            }

#pragma warning disable 56506 // [....], message.Properties is never null
            if (!message.Properties.ContainsKey(HttpRequestMessageProperty.Name))
            {
                return(this.catchAllOperationName);
            }
            HttpRequestMessageProperty prop = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
            if (prop == null)
            {
                return(this.catchAllOperationName);
            }
            string method = prop.Method;

            Uri to = message.Headers.To;
#pragma warning restore 56506

            if (to == null)
            {
                return(this.catchAllOperationName);
            }

            if (this.helpUriTable != null)
            {
                UriTemplateMatch match = this.helpUriTable.MatchSingle(to);
                if (match != null)
                {
                    uriMatched = true;
                    AddUriTemplateMatch(match, prop, message);
                    if (method == WebHttpBehavior.GET)
                    {
                        return(HelpOperationInvoker.OperationName);
                    }
                    message.Properties.Add(WebHttpDispatchOperationSelector.HttpOperationSelectorDataPropertyName,
                                           new WebHttpDispatchOperationSelectorData()
                    {
                        AllowedMethods = new List <string>()
                        {
                            WebHttpBehavior.GET
                        }
                    });
                    return(this.catchAllOperationName);
                }
            }

            UriTemplateTable methodSpecificTable;
            bool             methodMatchesExactly = methodSpecificTables.TryGetValue(method, out methodSpecificTable);
            if (methodMatchesExactly)
            {
                string operationName;
                uriMatched = CanUriMatch(methodSpecificTable, to, prop, message, out operationName);
                if (uriMatched)
                {
                    return(operationName);
                }
            }

            if (wildcardTable != null)
            {
                string operationName;
                uriMatched = CanUriMatch(wildcardTable, to, prop, message, out operationName);
                if (uriMatched)
                {
                    return(operationName);
                }
            }

            if (ShouldRedirectToUriWithSlashAtTheEnd(methodSpecificTable, message, to))
            {
                return(redirectOperationName);
            }

            // the {method, uri} pair does not match anything the service supports.
            // we know at this point that we'll return some kind of error code, but we
            // should go through all methods for the uri to see if any method is supported
            // so that that information could be returned to the user as well

            List <string> allowedMethods = null;
            foreach (KeyValuePair <string, UriTemplateTable> pair in methodSpecificTables)
            {
                if (pair.Key == method || pair.Key == WebHttpBehavior.WildcardMethod)
                {
                    // the uri must not match the uri template
                    continue;
                }
                UriTemplateTable table = pair.Value;
                if (table.MatchSingle(to) != null)
                {
                    if (allowedMethods == null)
                    {
                        allowedMethods = new List <string>();
                    }

                    //

                    if (!allowedMethods.Contains(pair.Key))
                    {
                        allowedMethods.Add(pair.Key);
                    }
                }
            }

            if (allowedMethods != null)
            {
                uriMatched = true;
                message.Properties.Add(WebHttpDispatchOperationSelector.HttpOperationSelectorDataPropertyName,
                                       new WebHttpDispatchOperationSelectorData()
                {
                    AllowedMethods = allowedMethods
                });
            }
            return(catchAllOperationName);
        }
        public void literal_takes_precedence_over_template()
        {
            var table = new UriTemplateTable(new Uri("http://localhost"),
                                             new List<KeyValuePair<UriTemplate, object>>
                                             {
                                                 new KeyValuePair<UriTemplate,object>(new UriTemplate("resource1/{resourceId}"), null),
                                                 new KeyValuePair<UriTemplate, object>(new UriTemplate("resource1/new"), null)
                                             });
            var match = table.Match("http://localhost/resource1/new".ToUri());

            match.ShouldHaveCountOf(2)
                    .First().Template.ToString().ShouldBe("/resource1/new");
        }
        public void FindTemplatesWithQueryStrings(string url, string key)
        {
            var table = new UriTemplateTable();   // More restrictive templates should have priority over less restrictuve ones
            table.Add("fooxy3", new UriTemplate("/foo?x={x}&y={y}"));
            table.Add("fooxy2", new UriTemplate("/foo?x={x}{&y}"));
            table.Add("fooxy4", new UriTemplate("/foo?x={x}{&z}"));
            table.Add("fooxy", new UriTemplate("/foo{?x,y}"));
            table.Add("foo", new UriTemplate("/foo"));
 

            var result = table.Match(new Uri(url, UriKind.RelativeOrAbsolute));

            if (string.IsNullOrEmpty(key))
            {
                Assert.Null(result);
            }
            else
            {
                Assert.Equal(key, result.Key);
            }
        }
        public WebHttpDispatchOperationSelector(ServiceEndpoint endpoint)
        {
            if (endpoint == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
            }
            if (endpoint.Address == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                                                              SR2.GetString(SR2.EndpointAddressCannotBeNull)));
            }
#pragma warning disable 56506 // [....], endpoint.Address.Uri is never null
            Uri baseUri = endpoint.Address.Uri;
            this.methodSpecificTables = new Dictionary <string, UriTemplateTable>();
            this.templates            = new Dictionary <string, UriTemplate>();
#pragma warning restore 56506

            WebHttpBehavior webHttpBehavior = endpoint.Behaviors.Find <WebHttpBehavior>();
            if (webHttpBehavior != null && webHttpBehavior.HelpEnabled)
            {
                this.helpUriTable = new UriTemplateTable(endpoint.ListenUri, HelpPage.GetOperationTemplatePairs());
            }

            Dictionary <WCFKey, string> alreadyHaves = new Dictionary <WCFKey, string>();

#pragma warning disable 56506 // [....], endpoint.Contract is never null
            foreach (OperationDescription od in endpoint.Contract.Operations)
#pragma warning restore 56506
            {
                // ignore callback operations
                if (od.Messages[0].Direction == MessageDirection.Input)
                {
                    string method = WebHttpBehavior.GetWebMethod(od);
                    string path   = UriTemplateClientFormatter.GetUTStringOrDefault(od);

                    //

                    if (UriTemplateHelpers.IsWildcardPath(path) && (method == WebHttpBehavior.WildcardMethod))
                    {
                        if (this.catchAllOperationName != "")
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                      new InvalidOperationException(
                                          SR2.GetString(SR2.MultipleOperationsInContractWithPathMethod,
                                                        endpoint.Contract.Name, path, method)));
                        }
                        this.catchAllOperationName = od.Name;
                    }
                    UriTemplate ut     = new UriTemplate(path);
                    WCFKey      wcfKey = new WCFKey(ut, method);
                    if (alreadyHaves.ContainsKey(wcfKey))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new InvalidOperationException(
                                      SR2.GetString(SR2.MultipleOperationsInContractWithPathMethod,
                                                    endpoint.Contract.Name, path, method)));
                    }
                    alreadyHaves.Add(wcfKey, od.Name);

                    UriTemplateTable methodSpecificTable;
                    if (!methodSpecificTables.TryGetValue(method, out methodSpecificTable))
                    {
                        methodSpecificTable = new UriTemplateTable(baseUri);
                        methodSpecificTables.Add(method, methodSpecificTable);
                    }

                    methodSpecificTable.KeyValuePairs.Add(new KeyValuePair <UriTemplate, object>(ut, od.Name));
                    this.templates.Add(od.Name, ut);
                }
            }

            if (this.methodSpecificTables.Count == 0)
            {
                this.methodSpecificTables = null;
            }
            else
            {
                // freeze all the tables because they should not be modified after this point
                foreach (UriTemplateTable table in this.methodSpecificTables.Values)
                {
                    table.MakeReadOnly(true /* allowDuplicateEquivalentUriTemplates */);
                }

                if (!methodSpecificTables.TryGetValue(WebHttpBehavior.WildcardMethod, out wildcardTable))
                {
                    wildcardTable = null;
                }
            }
        }