Beispiel #1
0
        /// <summary>
        /// Creates a list of path segments for the specified URI query.
        /// </summary>
        /// <param name="queryUri">The absolute URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>The <see cref="QueryToken"/> representing the query path.</returns>
        private QueryToken CreatePathSegments(Uri queryUri, Uri serviceBaseUri)
        {
            Debug.Assert(queryUri != null, "queryUri != null");
            Debug.Assert(serviceBaseUri != null, "serviceBaseUri != null");

            //// This method is a no-metadata, lexical only copy of RequestUriProcessor.CreateSegments

            List <string> uriSegments = this.EnumerateSegments(queryUri, serviceBaseUri);

            Debug.Assert(uriSegments.Count <= this.maxDepth, "uriSegments.Count <= this.maxDepth");

            // The segment before the one being processed
            SegmentQueryToken parentNode = null;

            foreach (string uriSegment in uriSegments)
            {
                Debug.Assert(uriSegment != null, "uriSegment != null");

                string segmentIdentifier;
                bool   hasKeyValues    = ExtractSegmentIdentifier(uriSegment, out segmentIdentifier);
                string keyValuesString = hasKeyValues ? uriSegment.Substring(segmentIdentifier.Length) : null;

                KeywordKind?keyword = QueryTokenUtils.ParseKeywordKind(segmentIdentifier);
                parentNode = keyword == null
                    ? new SegmentQueryToken(
                    segmentIdentifier,
                    parentNode,
                    hasKeyValues ? ParseKeyValues(keyValuesString) : null)
                    : new KeywordSegmentQueryToken(keyword.Value, parentNode);
            }

            return(parentNode);
        }
Beispiel #2
0
        /// <summary>
        /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="SyntacticTree"/>
        /// describing the query specified by the uri.
        /// </summary>
        /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param>
        /// <param name="serviceBaseUri">The base URI of the service.</param>
        /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param>
        /// <returns>A new instance of <see cref="SyntacticTree"/> which represents the query specified in the <paramref name="queryUri"/>.</returns>
        public static SyntacticTree ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth)
        {
            ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri");
            if (!queryUri.IsAbsoluteUri)
            {
                throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(queryUri), "queryUri");
            }

            ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri");
            if (!serviceBaseUri.IsAbsoluteUri)
            {
                throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri");
            }

            if (maxDepth <= 0)
            {
                throw new ArgumentException(Strings.SyntacticTree_MaxDepthInvalid, "maxDepth");
            }

            UriPathParser pathParser = new UriPathParser(maxDepth);
            var           path       = pathParser.ParsePathIntoSegments(queryUri, serviceBaseUri);

            List <CustomQueryOptionToken> queryOptions = UriUtils.ParseQueryOptions(queryUri);

            QueryToken filter      = null;
            string     filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption);

            if (filterQuery != null)
            {
                UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth);
                filter = expressionParser.ParseFilter(filterQuery);
            }

            IEnumerable <OrderByToken> orderByTokens = null;
            string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption);

            if (orderByQuery != null)
            {
                UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth);
                orderByTokens = expressionParser.ParseOrderBy(orderByQuery);
            }

            SelectToken select      = null;
            string      selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption);

            if (selectQuery != null)
            {
                ISelectExpandTermParser selectParser = SelectExpandTermParserFactory.Create(selectQuery);
                select = selectParser.ParseSelect();
            }

            ExpandToken expand      = null;
            string      expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption);

            if (expandQuery != null)
            {
                ISelectExpandTermParser expandParser = SelectExpandTermParserFactory.Create(expandQuery);
                expand = expandParser.ParseExpand();
            }

            int?   skip      = null;
            string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption);

            if (skipQuery != null)
            {
                int skipValue;
                if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue))
                {
                    throw new ODataException(Strings.SyntacticTree_InvalidSkipQueryOptionValue(skipQuery));
                }

                skip = skipValue;
            }

            int?   top      = null;
            string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption);

            if (topQuery != null)
            {
                int topValue;
                if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue))
                {
                    throw new ODataException(Strings.SyntacticTree_InvalidTopQueryOptionValue(topQuery));
                }

                top = topValue;
            }

            string          inlineCountQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.InlineCountQueryOption);
            InlineCountKind?inlineCount      = QueryTokenUtils.ParseInlineCountKind(inlineCountQuery);

            string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption);

            return(new SyntacticTree(
                       path,
                       filter,
                       orderByTokens,
                       select,
                       expand,
                       skip,
                       top,
                       inlineCount,
                       format,
                       queryOptions.Count == 0 ? null : new ReadOnlyCollection <CustomQueryOptionToken>(queryOptions)));
        }