Пример #1
0
        /// <summary>
        /// Retrieves the request bytes from disk or from the memory cache
        /// </summary>
        /// <param name="requestHeaderId"></param>
        /// <returns></returns>
        public byte[] LoadRequestData(int requestHeaderId)
        {
            byte[] result = new byte[0];
            try
            {
                lock (_lockData)                 //critical section begins
                {
                    TVRequestInfo reqInfo;
                    if (_requestInfos.TryGetValue(requestHeaderId, out reqInfo) && reqInfo.RequestLength > 0)
                    {
                        //check if the request is already in the buffer
                        ICacheable           entry   = RequestDataCache.Instance.GetEntry(_objectId ^ requestHeaderId);
                        RequestResponseBytes reqData = null;
                        if (entry != null)
                        {
                            reqData = entry.Reserve() as RequestResponseBytes;
                            entry.Release();
                        }

                        if (reqData != null && reqData.RawRequest != null)
                        {
                            result = reqData.RawRequest;
                        }
                        else
                        {
                            //load request from disk
                            int  length        = reqInfo.RequestLength;
                            long startPosition = reqInfo.RequestStartPosition;
                            result = DataRead(startPosition, length);

                            //save request to buffer if is not null
                            if (result.Length != 0)
                            {
                                BufferSaveRequest(requestHeaderId, result);
                            }
                        }

                        if (reqInfo.IsEncrypted && result != null && result.Length > 0)
                        {
                            //decrypt the request
                            result = Encryptor.Decrypt(result);
                        }
                    }
                }                 //critical section ends
            }
            catch (Exception ex)
            {
                SdkSettings.Instance.Logger.Log(TraceLevel.Error, "Cannot load request data for request id: {0} . Stack trace: {1}", requestHeaderId, ex.ToString());
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Commits a request to the memory cache
        /// </summary>
        /// <param name="reqHeaderId"></param>
        /// <param name="data"></param>
        private void BufferSaveRequest(int reqHeaderId, byte[] data)
        {
            if (!_cacheEnabled)
            {
                return;
            }

            ICacheable           entry = RequestDataCache.Instance.GetEntry(_objectId ^ reqHeaderId);
            RequestResponseBytes reqData;

            if (entry == null)
            {
                reqData            = new RequestResponseBytes();
                reqData.RawRequest = data;
                RequestDataCache.Instance.Add(_objectId ^ reqHeaderId, new CacheEntry(reqData));
            }
            else
            {
                reqData            = entry.Reserve() as RequestResponseBytes;
                reqData.RawRequest = data;
                entry.Release();
            }
        }
Пример #3
0
        /// <summary>
        /// Actually gets a matching response from the mock data
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        public HttpResponseInfo SendRequest(HttpRequestInfo requestInfo)
        {
            HttpResponseInfo  responseInfo         = null;
            string            currentRequestString = requestInfo.ToString();
            string            currentAlertId       = Utils.RegexFirstGroupValue(currentRequestString, ALERT_MATCH);
            TrafficServerMode currentMatchMode     = _matchMode;

            if (!String.IsNullOrEmpty(currentAlertId))             //override the redundancy tuning if we are trying to match a alert
            {
                currentMatchMode = TrafficServerMode.BrowserFriendly;
            }

            //parse the request variables because we will need them to construct the hash
            requestInfo.ParseVariables();


            TrafficServerResponseSet responseSet = null;

            //look in the server cache for the request
            ICacheable entry =
                TrafficServerCache.Instance.GetEntry(requestInfo.GetHashCode(currentMatchMode));


            if (entry != null)
            {
                responseSet = entry.Reserve() as TrafficServerResponseSet;
                entry.Release();
            }

            TrafficServerResponseSet similarRequests = new TrafficServerResponseSet();

            if (responseSet == null)
            {
                //create a new empty response set
                responseSet = new TrafficServerResponseSet();

                RequestSearcher searcher = new RequestSearcher();

                SearchCriteriaSet criteriaSet;

                criteriaSet = GetCriteriaSet(requestInfo, currentMatchMode);

                RequestMatches matches = new RequestMatches();

                //do the search!
                searcher.Search(_sourceStore, criteriaSet, matches);

                //normalize the matches and keep only the ones that have the same variables and values
                if (matches.Count > 0)
                {
                    HttpRequestInfo original;
                    HttpRequestInfo found;
                    byte[]          requestBytes;
                    int             i, n = matches.Count;
                    for (i = 0; i < n & i < MATCHES_LIMIT; i++)
                    {
                        int           match  = matches[i];
                        TVRequestInfo header = _sourceStore.GetRequestInfo(match);
                        if (_ignoreAuth)
                        {
                            if (
                                String.Compare(header.ResponseStatus, "401", true) == 0 ||
                                String.Compare(header.ResponseStatus, "407", true) == 0)
                            {
                                HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping authentication challenge");
                                //simply skip 401 matches
                                continue;
                            }
                        }

                        if (String.Compare(header.Description, Resources.TrafficLogProxyDescription, true) == 0)
                        {
                            //is likely that the source store is also the save store and this may be
                            //the current request being saved
                            HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping request to traffic store");
                            continue;
                        }


                        requestBytes = _sourceStore.LoadRequestData(match);
                        string requestString = Constants.DefaultEncoding.GetString(requestBytes);

                        if (String.IsNullOrEmpty(requestString))
                        {
                            continue;                             //skip the current match is incorrect
                        }
                        original = new HttpRequestInfo(DynamicElementsRemover.Remove(currentRequestString));
                        found    = new HttpRequestInfo(DynamicElementsRemover.Remove(requestString));

                        if (RequestMatcher.IsMatch(original, found, TrafficServerMode.Strict))
                        {
                            responseSet.Add(match);
                        }
                        else if (currentMatchMode != TrafficServerMode.Strict &&
                                 RequestMatcher.IsMatch(original, found, currentMatchMode))
                        {
                            similarRequests.Add(match);
                        }
                    }
                    //if no exact requests were found
                    if (responseSet.Count == 0 && similarRequests.Count > 0)
                    {
                        HttpServerConsole.Instance.WriteLine
                            (LogMessageType.Warning, "Warning, exact match was not found for {0} returning a similar request.",
                            requestInfo.RequestLine);
                    }
                    responseSet.AddRange(similarRequests.Matches);
                }

                //add this response set to the cache
                TrafficServerCache.Instance.Add(requestInfo.GetHashCode(currentMatchMode), new CacheEntry(responseSet));
            }

            //get the next response id from the response set
            int requestId = responseSet.GetNext();

            if (requestId == NULL_INDEX)
            {
                HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "(404) Request not found: {0}"
                                                     , requestInfo.RequestLine);
                //the request was not found at all, return a 404
                return(new HttpResponseInfo(HttpErrorResponse.GenerateHttpErrorResponse(HttpStatusCode.NotFound, "Request Not Found",
                                                                                        "<html><head><title>Error code: 404</title><body><h1>Request was not found or variables didn't match.</h1></body></html>")));
            }

            if (requestId != NULL_INDEX)
            {
                HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Returning response from request id: {0}", requestId);
                byte[] responseBytes = _sourceStore.LoadResponseData(requestId);

                if (responseBytes != null)
                {
                    responseInfo = new HttpResponseInfo(responseBytes);

                    if (!String.IsNullOrEmpty(currentAlertId))
                    {
                        Encoding encoding       = HttpUtil.GetEncoding(responseInfo.Headers["Content-Type"]);
                        string   responseString = encoding.GetString(responseBytes);
                        responseString = Utils.ReplaceGroups(responseString, ALERT_MATCH, currentAlertId);
                        responseInfo   = new HttpResponseInfo(encoding.GetBytes(responseString));
                    }
                }

                //add the request id header
                responseInfo.Headers.Add("Traffic-Store-Req-Id", requestId.ToString());
            }

            return(responseInfo);
        }
Пример #4
0
        /// <summary>
        /// Verifies a request
        /// </summary>
        /// <param name="dataSource"></param>
        /// <param name="header"></param>
        /// <param name="criteriaSet"></param>
        /// <param name="result"></param>
        protected override void RequestMatches(ITrafficDataAccessor dataSource, TVRequestInfo header, SearchCriteriaSet criteriaSet, ISearchResult result)
        {
            bool found   = false;
            int  hashSum = criteriaSet.DescriptionFilter.GetHashCode();

            List <MatchCoordinates> matchCoordinates;            //variable used to obtain match coordinates

            //create a temp list to store all the matches
            LineMatches tempMatches = new LineMatches();

            if (criteriaSet.DescriptionFilter == null ||
                criteriaSet.DescriptionFilter == String.Empty ||
                header.Description.IndexOf(criteriaSet.DescriptionFilter,
                                           StringComparison.CurrentCultureIgnoreCase) > -1)
            {
                //apply an AND operation with all the search criterias from the last search criteria cached

                int i, n = criteriaSet.Count, start = criteriaSet.StartCriteriaIndex;

                for (i = start; i < n; i++)
                {
                    ISearchCriteria criteria = criteriaSet[i];
                    found = false;
                    //compose the text to search
                    if (criteria.Context == SearchContext.RequestLine)
                    {
                        if (criteria.Matches(header.RequestLine, 0, out matchCoordinates))
                        {
                            //if we got here it means that the request line matches
                            //using the request search context since we really care only for request or response
                            found = true;
                            tempMatches.Add(new LineMatch(header.Id, header.RequestLine, matchCoordinates, SearchContext.Request));
                        }
                        else
                        {
                            found = false;
                            break;                             //one of the criteria did not match so the end result is false
                        }
                    }
                    else
                    {
                        //search in request first
                        if (criteria.Context == SearchContext.Full || criteria.Context == SearchContext.Request || criteria.Context == SearchContext.RequestBody)
                        {
                            found = SearchInContext(dataSource, header, criteria, SearchContext.Request, ref tempMatches);
                        }
                        if (criteria.Context == SearchContext.Full || criteria.Context == SearchContext.Response)
                        {
                            found |= SearchInContext(dataSource, header, criteria, SearchContext.Response, ref tempMatches);
                        }

                        if (!found)
                        {
                            break;                             //no match was found in the entire stream
                        }
                    }

                    //if at the end of criteria iteration found is still true cache the hashSum of this criteria
                    //so we can get the sublist of request ids in future searches
                    if (found)
                    {
                        hashSum = hashSum ^ criteria.GetHashCode();

                        SearchSubset subset = null;

                        ICacheable entry = SearchSubsetsCache.Instance.GetEntry(hashSum);

                        if (entry == null)
                        {
                            subset = new SearchSubset();
                            subset.Add(header.Id);
                            SearchSubsetsCache.Instance.Add(hashSum, new CacheEntry(subset));
                        }
                        else
                        {
                            subset = entry.Reserve() as SearchSubset;
                            if (!subset.Contains(header.Id))
                            {
                                subset.Add(header.Id);
                            }
                            entry.Release();
                        }
                    }
                }                 //end of for, all the criterias were matched or one criteria did not match

                if (found)
                {
                    //add all the temp matches to the results
                    result.AddRange(tempMatches);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Verifies that a request matches
        /// </summary>
        /// <param name="dataSource"></param>
        /// <param name="header"></param>
        /// <param name="criteriaSet"></param>
        /// <param name="result"></param>
        protected override void RequestMatches(ITrafficDataAccessor dataSource, TVRequestInfo header, SearchCriteriaSet criteriaSet, ISearchResult result)
        {
            bool found   = true;
            int  hashSum = criteriaSet.DescriptionFilter.GetHashCode();

            if (criteriaSet.DescriptionFilter == null ||
                criteriaSet.DescriptionFilter == String.Empty ||
                header.Description.IndexOf(criteriaSet.DescriptionFilter,
                                           StringComparison.CurrentCultureIgnoreCase) > -1)
            {
                //apply an AND operation with all the search criterias from the last search criteria cached

                int i, n = criteriaSet.Count, start = criteriaSet.StartCriteriaIndex;

                for (i = start; i < n; i++)
                {
                    ISearchCriteria criteria = criteriaSet[i];
                    //compose the text to search
                    string toBeSearched;

                    if (criteria.Context == SearchContext.RequestLine)
                    {
                        toBeSearched = header.RequestLine;
                    }
                    else if (criteria.Context == SearchContext.RequestBody || criteria.Context == SearchContext.Request)
                    {
                        toBeSearched = Constants.DefaultEncoding.GetString(dataSource.LoadRequestData(header.Id));
                        if (criteria.Context == SearchContext.RequestBody)
                        {
                            HttpRequestInfo reqInfo = new HttpRequestInfo(toBeSearched);
                            toBeSearched = reqInfo.ContentDataString;
                        }
                    }
                    else if (criteria.Context == SearchContext.Response)
                    {
                        toBeSearched = Constants.DefaultEncoding.GetString(dataSource.LoadResponseData(header.Id));
                    }
                    else
                    {
                        string        request  = Constants.DefaultEncoding.GetString(dataSource.LoadRequestData(header.Id));
                        string        response = Constants.DefaultEncoding.GetString(dataSource.LoadResponseData(header.Id));
                        StringBuilder sb       = new StringBuilder(request.Length + response.Length);
                        sb.Append(request);
                        sb.Append(response);
                        toBeSearched = sb.ToString();
                    }

                    found = criteria.Matches(toBeSearched);

                    if (found)                     //if found is still true cache the request id as a match for the current set of criterias
                    {
                        hashSum = hashSum ^ criteria.GetHashCode();

                        ICacheable entry = SearchSubsetsCache.Instance.GetEntry(hashSum);

                        SearchSubset subset;

                        if (entry == null)
                        {
                            subset = new SearchSubset();
                            subset.Add(header.Id);
                            SearchSubsetsCache.Instance.Add(hashSum, new CacheEntry(subset));
                        }
                        else
                        {
                            subset = entry.Reserve() as SearchSubset;
                            //if (!subset.Contains(header.Id)) //not checking if the entry exists for performance reasons
                            //{
                            subset.Add(header.Id);
                            //}
                            entry.Release();
                        }
                    }
                    else
                    {
                        break;    //criteria didn't match, break the loop
                    }
                }                 //end of for, all the criterias were matched or one criteria did not match

                if (found)
                {
                    //add all the temp matches to the results
                    result.Add(header.Id);
                }
            }            //end description check
        }