/** * Process the request Uri and creates an instance of * RequestDescription from the processed uri. * * @param IService $service Reference to the data service instance. * * @return RequestDescription * * @throws ODataException If any exception occurs while processing the segments * or in case of any version incompatibility. */ public static function process(IService $service) { $host = $service->getHost(); $absoluteRequestUri = $host->getAbsoluteRequestUri(); $absoluteServiceUri = $host->getAbsoluteServiceUri(); $requestUriSegments = array_slice($absoluteRequestUri->getSegments(), $absoluteServiceUri->getSegmentCount()); $segments = SegmentParser::parseRequestUriSegments($requestUriSegments, $service->getProvidersWrapper(), true); $request = new RequestDescription($segments, $absoluteRequestUri, $service->getConfiguration()->getMaxDataServiceVersion(), $host->getRequestVersion(), $host->getRequestMaxVersion()); $kind = $request->getTargetKind(); if ($kind == TargetKind::METADATA() || $kind == TargetKind::BATCH() || $kind == TargetKind::SERVICE_DIRECTORY()) { return $request; } if ($kind == TargetKind::PRIMITIVE_VALUE() || $kind == TargetKind::MEDIA_RESOURCE()) { // http://odata/NW.svc/Orders/$count // http://odata/NW.svc/Orders(123)/Customer/CustomerID/$value // http://odata/NW.svc/Employees(1)/$value // http://odata/NW.svc/Employees(1)/ThumbNail_48X48/$value $request->setContainerName($segments[count($segments) - 2]->getIdentifier()); } else { $request->setContainerName($request->getIdentifier()); } if ($request->getIdentifier() === ODataConstants::URI_COUNT_SEGMENT) { if (!$service->getConfiguration()->getAcceptCountRequests()) { throw ODataException::createBadRequestError(Messages::configurationCountNotAccepted()); } $request->queryType = QueryType::COUNT(); // use of $count requires request DataServiceVersion // and MaxDataServiceVersion greater than or equal to 2.0 $request->raiseResponseVersion(2, 0); $request->raiseMinVersionRequirement(2, 0); } else { if ($request->isNamedStream()) { $request->raiseMinVersionRequirement(3, 0); } else { if ($request->getTargetKind() == TargetKind::RESOURCE()) { if (!$request->isLinkUri()) { $resourceSetWrapper = $request->getTargetResourceSetWrapper(); //assert($resourceSetWrapper != null) $hasNamedStream = $resourceSetWrapper->hasNamedStreams($service->getProvidersWrapper()); $hasBagProperty = $resourceSetWrapper->hasBagProperty($service->getProvidersWrapper()); if ($hasNamedStream || $hasBagProperty) { $request->raiseResponseVersion(3, 0); } } } else { if ($request->getTargetKind() == TargetKind::BAG()) { $request->raiseResponseVersion(3, 0); } } } } return $request; }
public function testProcessRequestForCollectionWithInlineCountWhenCountsAreDisabled() { $requestURI = new Url('http://host.com/data.svc/Collection/?$inlinecount=allpages'); Phockito::when($this->mockServiceHost->getAbsoluteRequestUri())->return($requestURI); //mock inline count as all pages Phockito::when($this->mockServiceHost->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT))->return("allpages"); $this->fakeServiceConfig->setAcceptCountRequests(false); try { UriProcessor::process($this->mockService); $this->fail("Expected exception not thrown"); } catch (ODataException $ex) { $expected = Messages::configurationCountNotAccepted(); $this->assertEquals($expected, $ex->getMessage(), $ex->getTraceAsString()); } }
/** * Process the $inlinecount option and update the request description. * * @return void * * @throws ODataException Throws bad request error in the following cases * (1) If $inlinecount is disabled by the developer * (2) If both $count and $inlinecount specified * (3) If $inlinecount value is unknown * (4) If capability negotiation over version fails */ private function _processCount() { $inlineCount = $this->service->getHost()->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT); //If it's not specified, we're done if (is_null($inlineCount)) { return; } //If the service doesn't allow count requests..then throw an exception if (!$this->service->getConfiguration()->getAcceptCountRequests()) { throw ODataException::createBadRequestError(Messages::configurationCountNotAccepted()); } $inlineCount = trim($inlineCount); //if it's set to none, we don't do inline counts if ($inlineCount === ODataConstants::URI_ROWCOUNT_OFFOPTION) { return; } //You can't specify $count & $inlinecount together //TODO: ensure there's a test for this case see #55 if ($this->request->queryType == QueryType::COUNT()) { throw ODataException::createBadRequestError(Messages::queryProcessorInlineCountWithValueCount()); } $this->_checkSetQueryApplicable(); //TODO: why do we do this check? if ($inlineCount === ODataConstants::URI_ROWCOUNT_ALLOPTION) { $this->request->queryType = QueryType::ENTITIES_WITH_COUNT(); $this->request->raiseMinVersionRequirement(2, 0); $this->request->raiseResponseVersion(2, 0); } else { throw ODataException::createBadRequestError(Messages::queryProcessorInvalidInlineCountOptionError()); } }