Esempio n. 1
0
 /**
  * Process an incoming request.
  * Determine the appropriate route for the request using a Router, and then
  * execute the resource method to obtain and return a result.
  *
  * @param \Sonno\Http\Request\RequestInterface $request The incoming request
  * @throws MalformedResourceRepresentationException
  * @throws \Sonno\Http\Exception\NotAcceptableException
  * @return \Sonno\Http\Response\Response
  */
 public function run(RequestInterface $request)
 {
     $selectedVariant = $result = null;
     try {
         // attempt to find routes that match the current request
         $router = new Router($this->_config);
         $routes = $router->match($request, $pathParams);
         // construct a hash map of Variants based on Routes
         $variantMap = array();
         // variant hash => <Sonno\Http\Variant>
         $variants = array();
         // array<Sonno\Http\Variant>
         /** @var $route \Sonno\Configuration\Route */
         foreach ($routes as $route) {
             $routeProduces = $route->getProduces();
             foreach ($routeProduces as $produces) {
                 $variant = new Variant(null, null, $produces);
                 $variantHash = spl_object_hash($variant);
                 $variantMap[$variantHash] = $route;
                 $variants[] = $variant;
             }
         }
         // select a Variant and find the corresponding route
         $selectedVariant = $request->selectVariant($variants);
         if (null == $selectedVariant) {
             throw new NotAcceptableException();
         }
         $selectedVariantHash = spl_object_hash($selectedVariant);
         $selectedRoute = $variantMap[$selectedVariantHash];
         // maintain URI information for resource class context injection
         $uriInfo = new UriInfo($this->_config, $request, $selectedRoute);
         $uriInfo->setPathParameters($pathParams);
         $uriInfo->setQueryParameters($request->getQueryParams());
         // execute the resource class method and obtain the result
         $dispatcher = $this->getDispatcher();
         $dispatcher->setRequest($request);
         $dispatcher->setUriInfo($uriInfo);
         $result = $dispatcher->dispatch($selectedRoute);
     } catch (MethodNotAllowedException $e) {
         // rewrite the response as a 200 OK when the request is OPTIONS
         if ('OPTIONS' == $request->getMethod()) {
             $e->getResponse()->setStatusCode(200);
         }
         $result = $e->getResponse();
     } catch (WebApplicationException $e) {
         $result = $e->getResponse();
     }
     // object is a scalar value: construct a new Response
     if (is_scalar($result)) {
         $response = new Response(200, $result);
         // object is already a Response
     } else {
         if ($result instanceof Response) {
             $response = $result;
             // object implements the Renderable interface: construct a Response
             // using the representation produced by render()
         } else {
             if ($result instanceof Renderable) {
                 $response = new Response(200, $result->render($selectedVariant));
                 // cannot determine how to handle the object returned
             } else {
                 throw new MalformedResourceRepresentationException();
             }
         }
     }
     // ensure a Content-Type header is present
     if (!$response->hasHeader('Content-Type') && $response->getStatusCode() < 300 && $response->getContent()) {
         $response->setHeaders(array('Content-Type' => $selectedVariant->getMediaType()));
     }
     // ensure a Content-Length header is present
     if (!$response->hasHeader('Content-Length')) {
         $response->setHeaders(array('Content-Length' => strlen($response->getContent())));
     }
     // process any HTTP status filter callbacks
     $statusCode = $response->getStatusCode();
     if (isset($this->_responseFilters[$statusCode])) {
         foreach ($this->_responseFilters[$statusCode] as $filterCallback) {
             $filterCallback($request, $response);
         }
     }
     $response->sendResponse();
     return $response;
 }
Esempio n. 2
0
 /**
  * Test matching two paths that match, with a RegExp-constrained Path
  * parameter, but fail because the parameter value doesn't match the
  * regular expression.
  *
  * @return void
  * @expectedException \Sonno\Http\Exception\NotFoundException
  */
 public function testFailedPathMatchWithConstrainedParameters()
 {
     $route = $this->getMockBuilder('Sonno\\Configuration\\Route')->disableOriginalConstructor()->getMock();
     $route->expects($this->any())->method('getPath')->will($this->returnValue('/users/{id: \\d+}'));
     $config = $this->getMockBuilder('Sonno\\Configuration\\Configuration')->disableOriginalConstructor()->getMock();
     $config->expects($this->any())->method('getRoutes')->will($this->returnValue(array($route)));
     $request = $this->buildMockRequest('GET', '/users/abc');
     $router = new Router($config);
     $router->match($request, $params);
 }