예제 #1
0
			public MultiGetHttpContext(IRavenHttpConfiguration configuration, IHttpContext realContext, GetRequest req)
			{
				this.configuration = configuration;
				this.realContext = realContext;
				getResponse = new GetResponse();
				Request = new MultiGetHttpRequest(req, realContext.Request);
				Response = new MultiGetHttpResponse(getResponse, realContext.Response);
			}
예제 #2
0
		private void HandleRequest(GetRequest[] requests, GetResponse[] results, int i, IHttpContext context, IRavenHttpConfiguration ravenHttpConfiguration, MultiGetHttpContext[] contexts)
		{
			var request = requests[i];
			if (request == null)
				return;
			server.HandleActualRequest(contexts[i]);
			results[i] = contexts[i].Complete();
		}
예제 #3
0
		private void HandleRequest(GetRequest[] requests, GetResponse[] results, int i, IHttpContext context, IRavenHttpConfiguration ravenHttpConfiguration)
		{
			var request = requests[i];
			if (request == null)
				return;
			var ctx = new MultiGetHttpContext(ravenHttpConfiguration, context, request, TenantId);
			server.HandleActualRequest(ctx);
			results[i] = ctx.Complete();
		}
예제 #4
0
		private void HandleRequest(GetRequest[] requests, GetResponse[] results, int i, IHttpContext context, InMemoryRavenConfiguration ravenHttpConfiguration, MultiGetHttpContext[] contexts)
		{
			var request = requests[i];
			if (request == null)
				return;
		    ravenHttpConfiguration.ConcurrentMultiGetRequests.Wait();
		    try
		    {
		        server.HandleActualRequest(contexts[i]);
		    }
		    finally 
            {
                ravenHttpConfiguration.ConcurrentMultiGetRequests.Release();
		    }
			results[i] = contexts[i].Complete();
		}
예제 #5
0
		public MultiGetOperation(
			IHoldProfilingInformation holdProfilingInformation,
			DocumentConvention convention,
			string url,
			GetRequest[] requests)
		{
			this.holdProfilingInformation = holdProfilingInformation;
			this.convention = convention;
			this.url = url;
			this.requests = requests;

			requestUri = url + "/multi_get";
			if (convention.UseParallelMultiGet)
			{
				requestUri += "?parallel=yes";
			}
		}
예제 #6
0
		public GetRequest[] PreparingForCachingRequest(HttpJsonRequestFactory jsonRequestFactory)
		{
			cachedData = new CachedRequest[requests.Length];
			var requestsForServer = new GetRequest[requests.Length];
			Array.Copy(requests, 0, requestsForServer, 0, requests.Length);
			if (jsonRequestFactory.DisableHttpCaching == false && convention.ShouldCacheRequest(requestUri))
			{
				for (int i = 0; i < requests.Length; i++)
				{
					var request = requests[i];
					var cachingConfiguration = jsonRequestFactory.ConfigureCaching(url + request.UrlAndQuery,
																				   (key, val) => request.Headers[key] = val);
					cachedData[i] = cachingConfiguration.CachedRequest;
					if (cachingConfiguration.SkipServerCheck)
						requestsForServer[i] = null;
				}
			}
			allRequestsCanBeServedFromAggressiveCache = requestsForServer.All(x => x == null);
			return requestsForServer;
		}
예제 #7
0
		private void Executerequests(
			IHttpContext context, 
			IRavenHttpConfiguration ravenHttpConfiguration, 
			GetResponse[] results,
			GetRequest[] requests)
		{
			if ("yes".Equals(context.Request.QueryString["parallel"], StringComparison.InvariantCultureIgnoreCase))
			{
				Parallel.For(0, requests.Length, position =>
					HandleRequest(requests, results, position, context, ravenHttpConfiguration)
					);
			}
			else
			{
				for (var i = 0; i < requests.Length; i++)
				{
					HandleRequest(requests, results, i, context, ravenHttpConfiguration);
				}
			}
		}
예제 #8
0
		private void Executerequests(
			IHttpContext context, 
			IRavenHttpConfiguration ravenHttpConfiguration, 
			GetResponse[] results,
			GetRequest[] requests)
		{
			// Need to create this here to preserve any current TLS data that we have to copy
			var contexts = requests.Select(request => new MultiGetHttpContext(ravenHttpConfiguration, context, request, TenantId))
				.ToArray();
			if ("yes".Equals(context.Request.QueryString["parallel"], StringComparison.InvariantCultureIgnoreCase))
			{
				Parallel.For(0, requests.Length, position =>
					HandleRequest(requests, results, position, context, ravenHttpConfiguration, contexts)
					);
			}
			else
			{
				for (var i = 0; i < requests.Length; i++)
				{
					HandleRequest(requests, results, i, context, ravenHttpConfiguration, contexts);
				}
			}
		}
예제 #9
0
		private async Task HandleRequestAsync(GetRequest[] requests, HttpResponseMessage[] results, int i)
		{
			var request = requests[i];
			if (request == null)
				return;

			results[i] = await HandleActualRequestAsync(request);
		}
예제 #10
0
		private async Task ExecuteRequests(HttpResponseMessage[] results, GetRequest[] requests)
		{
			// Need to create this here to preserve any current TLS data that we have to copy
			if ("yes".Equals(GetQueryStringValue("parallel"), StringComparison.OrdinalIgnoreCase))
			{
				var tasks = new Task[requests.Length];
				Parallel.For(0, requests.Length, position =>
					tasks[position] = HandleRequestAsync(requests, results, position)
					);
				await Task.WhenAll(tasks);
			}
			else
			{
				for (var i = 0; i < requests.Length; i++)
				{
					await HandleRequestAsync(requests, results, i);
				}
			}
		}
예제 #11
0
			public MultiGetHttpContext(IRavenHttpConfiguration configuration, IHttpContext realContext, GetRequest req, string tenantId)
			{
				this.configuration = configuration;
				this.realContext = realContext;
				this.tenantId = tenantId;
				getResponse = new GetResponse();
				if (req == null)
					return;
				Request = new MultiGetHttpRequest(req, realContext.Request);
				Response = new MultiGetHttpResponse(getResponse, realContext.Response);
			}
예제 #12
0
			public MultiGetHttpRequest(GetRequest req, IHttpRequest realRequest)
			{
				var tempQueryString = HttpUtility.ParseQueryString(req.Query ?? "");
				QueryString = new NameValueCollection();
				foreach (string key in tempQueryString)
				{
					var values = tempQueryString.GetValues(key);
					if(values == null)
						continue;
					foreach (var value in values)
					{
						QueryString.Add(key, HttpUtility.UrlDecode(value));
					}
				}
				Url = new UriBuilder(realRequest.Url)
				{
					Query = req.Query,
					Path = req.Url
				}.Uri;
				RawUrl = Url.ToString();
				Headers = new NameValueCollection();
				foreach (var header in req.Headers)
				{
					Headers.Add(header.Key, header.Value);
				}
			}
예제 #13
0
		private async Task HandleRequestAsync(GetRequest[] requests, Tuple<HttpResponseMessage, List<Action<StringBuilder>>>[] results, int i)
		{
			var request = requests[i];
			if (request == null)
				return;

			results[i] = await HandleActualRequestAsync(request);

		}
예제 #14
0
			public MultiGetHttpRequest(GetRequest req, IHttpRequest realRequest)
			{
			    string ravenClientVersion;
			    req.Headers.TryGetValue(Constants.RavenClientVersion, out ravenClientVersion);
			    QueryString = HttpRequestHelper.ParseQueryStringWithLegacySupport(
                                                    ravenClientVersion, 
                                                    (req.Query ?? string.Empty).Replace("+", "%2B"));

				
				Url = new UriBuilder(realRequest.Url)
				{
					Query = req.Query,
					Path = req.Url
				}.Uri;
				RawUrl = req.Url;
				IsLocal = realRequest.IsLocal;
				Headers = new NameValueCollection();
				foreach (var header in req.Headers)
				{
					Headers.Add(header.Key, header.Value);
				}
			}
예제 #15
0
		public Task<GetResponse[]> MultiGetAsync(GetRequest[] requests)
		{
			return new CompletedTask<GetResponse[]>(databaseCommands.MultiGet(requests));
		}
예제 #16
0
		private async Task<HttpResponseMessage> HandleActualRequestAsync(GetRequest request)
		{
			var query = "";
			if (request.Query != null)
				query = request.Query.TrimStart('?').Replace("+", "%2B");

			string indexQuery = null;
			string modifiedQuery;

			// to avoid UriFormatException: Invalid URI: The Uri string is too long. [see RavenDB-1517]
			if (query.Length > 32760 && TryExtractIndexQuery(query, out modifiedQuery, out indexQuery))
			{
				query = modifiedQuery;
			}

			var msg = new HttpRequestMessage(HttpMethod.Get, new UriBuilder
			{
				Host = "multi.get",
				Query = query, 
				Path = request.Url
			}.Uri);
			msg.SetConfiguration(Configuration);
			var route = Configuration.Routes.GetRouteData(msg);
			msg.SetRouteData(route);
			var controllerSelector = new DefaultHttpControllerSelector(Configuration);
			var descriptor = controllerSelector.SelectController(msg);

			foreach (var header in request.Headers)
			{
				msg.Headers.TryAddWithoutValidation(header.Key, header.Value);
			}

			msg.Headers.TryAddWithoutValidation("Raven-internal-request", "true");

			var controller = (RavenBaseApiController)descriptor.CreateController(msg);
			controller.Configuration = Configuration;
			var controllerContext = new HttpControllerContext(Configuration, route, msg)
			{
				ControllerDescriptor = descriptor,
				Controller = controller,
				RequestContext = new HttpRequestContext(),
				RouteData = route
			};
			controller.SkipAuthorizationSinceThisIsMultiGetRequestAlreadyAuthorized = true;
			controller.ControllerContext = controllerContext;
			controllerContext.Request = msg;
			controller.RequestContext = controllerContext.RequestContext;
			controller.Configuration = Configuration;

			if (string.IsNullOrEmpty(indexQuery) == false && (controller as RavenDbApiController) != null)
			{
				((RavenDbApiController)controller).SetPostRequestQuery(indexQuery);
			}

			return await controller.ExecuteAsync(controllerContext, CancellationToken.None);
		}
예제 #17
0
		/// <summary>
		/// Perform a single POST requst containing multiple nested GET requests
		/// </summary>
		public Task<GetResponse[]> MultiGetAsync(GetRequest[] requests)
		{

			var multiGetOperation = new MultiGetOperation(this,  convention, url, requests);

			var httpJsonRequest = jsonRequestFactory.CreateHttpJsonRequest(new CreateHttpJsonRequestParams(this, multiGetOperation.RequestUri, "POST", credentials, convention));

			var requestsForServer = multiGetOperation.PreparingForCachingRequest(jsonRequestFactory);

			var postedData = JsonConvert.SerializeObject(requestsForServer);

			if (multiGetOperation.CanFullyCache(jsonRequestFactory, httpJsonRequest, postedData))
			{
				var cachedResponses = multiGetOperation.HandleCachingResponse(new GetResponse[requests.Length], jsonRequestFactory)	;
				return Task.Factory.StartNew(() => cachedResponses);
			}


			return Task.Factory.FromAsync(httpJsonRequest.BeginWrite, httpJsonRequest.EndWrite, postedData, null)
				.ContinueWith(
					task =>
					{
						task.Wait();// will throw on error
						return httpJsonRequest.ReadResponseJsonAsync()
							.ContinueWith(replyTask =>
							{
								var responses = convention.CreateSerializer().Deserialize<GetResponse[]>(new RavenJTokenReader(replyTask.Result));
								return multiGetOperation.HandleCachingResponse(responses, jsonRequestFactory);
							})
						;
					})
					.Unwrap();

		}
예제 #18
0
			public MultiGetHttpRequest(GetRequest req, IHttpRequest realRequest)
			{
				this.req = req;
				QueryString = HttpUtility.ParseQueryString(req.Query ?? "");
				Url = new UriBuilder(realRequest.Url)
				{
					Query = req.Query,
					Path = req.Url
				}.Uri;
				RawUrl = Url.ToString();
				Headers = new NameValueCollection();
				foreach (var header in req.Headers)
				{
					Headers.Add(header.Key, header.Value);
				}
			}