/** * @test */ public function willReturnNullWhenMatchWasNotFound() { $this->request = $this->request->withHeader('Accept', 'text/html'); $this->negotiator->expects($this->once())->method('getBest')->will($this->returnValue(null)); $bestMatch = $this->manager->getBestMatch($this->request); $this->assertNull($bestMatch); }
/** * Returns the "best match" of the given $priorities. Will return null in case * no match could be identified or a string containing the best matching Accept * header. * * @param MessageInterface $request * @param array $priorities A set of priorities. * @return null|string */ public function getBestMatch(MessageInterface $request, array $priorities = array()) { if (!$request->hasHeader('Accept')) { return null; } $header = $this->negotiator->getBest(implode(',', $request->getHeader('Accept')), $priorities); if ($header instanceof AcceptHeader) { return $header->getValue(); } return null; }
/** * @param Request $request * @param array $data * @param int $status * * @return Response */ public function negociate(Request $request, array $data = [], $status = Response::HTTP_OK) { $acceptHeader = $request->getHeader('Accept') ? $request->getHeader('Accept') : 'application/json'; $priorities = ['application/json', 'text/html; charset=UTF-8']; $mediaType = $this->negotiator->getBest($acceptHeader, $priorities); $value = $mediaType->getValue(); if ($value == 'text/html; charset=UTF-8') { return new Response(print_r($data, true), $status); } return new JsonResponse($data, $status); }
public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); foreach ($this->customFormats as $format => $mimeTypes) { $request->setFormat($format, $mimeTypes); } $format = $this->negotiator->getBest($request->headers->get('accept', '*/*'), $this->priorities); if (!$format instanceof Accept) { throw new HttpException(406); } $request->setRequestFormat($request->getFormat($format->getValue())); }
/** * Retrieve the formatter to use for the current request. * * Uses content negotiation to find the best available output format for * the requested content type. * * @param ServerRequestInterface $request * * @return FormatterInterface */ protected function formatter(ServerRequestInterface $request) { $accept = $request->getHeaderLine('Accept'); $priorities = $this->priorities(); if (!empty($accept)) { $preferred = $this->negotiator->getBest($accept, array_keys($priorities)); } if (!empty($preferred)) { $formatter = $priorities[$preferred->getValue()]; } else { $formatter = array_shift($priorities); } return $this->resolve($formatter); }
/** * @dataProvider dataProviderForTestGetBest */ public function testGetBest($header, $priorities, $expected) { try { $acceptHeader = $this->negotiator->getBest($header, $priorities); if ($acceptHeader === null) { $this->assertNull($expected); } else { $this->assertInstanceOf('Negotiation\\Accept', $acceptHeader); $this->assertSame($expected[0], $acceptHeader->getType()); $this->assertSame($expected[1], $acceptHeader->getParameters()); } } catch (\Exception $e) { $this->assertEquals($expected, $e); } }
/** * @param string $acceptHeader * @param string[] $acceptedContentTypes * @return bool */ public function matches($acceptHeader, array $acceptedContentTypes) { if (empty($acceptHeader)) { return false; } // This is in case the submitted header is not standards compliant if (strpos($acceptHeader, ';')) { list($acceptHeader, ) = explode(';', $acceptHeader); } $format = $this->negotiator->getBest($acceptHeader, $acceptedContentTypes); if ($format) { return true; } return false; }
static function guessBestFormat() { $negotiator = new Negotiator(); $acceptHeader = $_SERVER['HTTP_ACCEPT']; $priorities = array('text/html; charset=UTF-8', 'application/json'); $value = $negotiator->getBest($acceptHeader, $priorities)->getValue(); switch ($value) { case 'application/json': return 'json'; break; case 'text/html': return 'html'; break; } }
/** * Ensure the provided content type is valid and set the proper response content type * * @see \Slim\Middleware::call() */ public function call() { if (!$this->responseShouldHaveBody()) { $this->next->call(); return; } $negotiator = new Negotiator(); $format = $negotiator->getBest($this->app->request()->headers('Accept')); if ($format && in_array($type = $format->getValue(), $this->validContentTypes)) { $this->app->contentType($type); $this->next->call(); return; } $this->app->status(406); //Not acceptable }
/** * Handles a request to convert it to a response * * @param Request $request A Request instance * @param int $type The type of the request * @param bool $catch Whether to catch exceptions or not * * @return Response * * @throws Exception When an Exception occurs during processing */ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { $acceptHeader = $request->headers->get('Accept'); if ($acceptHeader !== null && !empty($this->formatPriorities)) { $accept = $this->formatNegotiator->getBest($acceptHeader, $this->formatPriorities); $request->attributes->set('_accept', $accept); if ($accept !== null) { /** @var Accept $accept */ if (false === strpos($accept->getType(), '*')) { $mimeType = $accept->getType(); $format = $this->getFormat($mimeType); $request->attributes->set('_mime_type', $mimeType); $request->attributes->set('_format', $format); } } } $acceptLanguageHeader = $request->headers->get('Accept-Language'); if ($acceptLanguageHeader !== null && !empty($this->languagePriorities)) { $acceptLanguage = $this->languageNegotiator->getBest($acceptLanguageHeader, $this->languagePriorities); $request->attributes->set('_accept_language', $acceptLanguage); if ($acceptLanguage !== null) { /** @var AcceptLanguage $acceptLanguage */ $language = $acceptLanguage->getType(); $request->attributes->set('_language', $language); } } $acceptEncodingHeader = $request->headers->get('Accept-Encoding'); if ($acceptEncodingHeader !== null && !empty($this->encodingPriorities)) { $acceptEncoding = $this->encodingNegotiator->getBest($acceptEncodingHeader, $this->encodingPriorities); $request->attributes->set('_accept_encoding', $acceptEncoding); if ($acceptEncoding !== null) { /** @var AcceptEncoding $acceptEncoding */ $encoding = $acceptEncoding->getType(); $request->attributes->set('_encoding', $encoding); } } $acceptCharsetHeader = $request->headers->get('Accept-Charset'); if ($acceptCharsetHeader !== null && !empty($this->charsetPriorities)) { $acceptCharset = $this->charsetNegotiator->getBest($acceptCharsetHeader, $this->charsetPriorities); $request->attributes->set('_accept_charset', $acceptCharset); if ($acceptCharset !== null) { /** @var AcceptCharset $acceptCharset */ $charset = $acceptCharset->getType(); $request->attributes->set('_charset', $charset); } } try { $this->decodeBody($request); } catch (BadRequestHttpException $exception) { if ($catch === true) { return $this->handleException($exception, $request); } throw $exception; } return $this->kernel->handle($request, $type, $catch); }
/** * {@inheritdoc} * The best format is also determined in function of the bundle configuration. */ public function getBest($header, array $priorities = array()) { $request = $this->requestStack->getCurrentRequest(); if (empty($header)) { $header = $request->headers->get('Accept'); } foreach ($this->map as $elements) { // Check if the current RequestMatcherInterface matches the current request if (null === $elements[0] || !$elements[0]->matches($request)) { continue; } $options =& $elements[1]; // Do not reallow memory for this variable if (!empty($options['stop'])) { throw new StopFormatListenerException('Stopped format listener'); } if (empty($options['priorities']) && empty($priorities)) { if (!empty($options['fallback_format'])) { return new Accept($request->getMimeType($options['fallback_format'])); } continue; } if ($options['prefer_extension']) { // ensure we only need to compute $extensionHeader once if (!isset($extensionHeader)) { if (preg_match('/.*\\.([a-z0-9]+)$/', $request->getPathInfo(), $matches)) { $extension = $matches[1]; } // $extensionHeader will now be either a non empty string or an empty string $extensionHeader = isset($extension) ? (string) $request->getMimeType($extension) : ''; if ($header && $extensionHeader) { $extensionHeader = ',' . $extensionHeader; } } if ($extensionHeader) { $header .= $extensionHeader . '; q=' . $options['prefer_extension']; } } $mimeTypes = $this->normalizePriorities(empty($priorities) ? $options['priorities'] : $priorities); $mimeType = parent::getBest($header, $mimeTypes); if ($mimeType !== null && !$mimeType->isMediaRange()) { return $mimeType; } if (isset($options['fallback_format']) && false !== $options['fallback_format']) { // if false === fallback_format then we fail here instead of considering more rules if (false === $options['fallback_format']) { return; } // stop looking at rules since we have a fallback defined return new Accept($request->getMimeType($options['fallback_format'])); } } return; }
public static function negotiate(Request $request, array $formats = null, array $priorities = null) { $formats = $formats ?: self::$defaultFormats; self::extendRequestFormats($request, $formats); if (null === $priorities) { $priorities = self::buildPrioritiesFromFormats($formats); } $acceptHeader = $request->headers->get('Accept'); if (!$acceptHeader) { return; } $negotiator = new Negotiator(); /** @var Accept $accept */ $accept = $negotiator->getBest($acceptHeader, $priorities); if (!$accept) { return; } $request->attributes->set('_mime_type', $accept->getValue()); $request->setRequestFormat($request->getFormat($accept->getType())); }
/** * Determine the preferred content type for the current request * * @param ServerRequestInterface $request * * @return string */ private function type(ServerRequestInterface $request) { $accept = $request->getHeaderLine('Accept'); $priorities = $this->preferences->toArray(); if (!empty($accept)) { $preferred = $this->negotiator->getBest($accept, array_keys($priorities)); } if (!empty($preferred)) { return $preferred->getValue(); } return key($priorities); }
/** * {@inheritdoc} * The best format is also determined in function of the bundle configuration. * * @throws StopFormatListenerException */ public function getBest($header, array $priorities = []) { $request = $this->getRequest(); $header = $header ?: $request->headers->get('Accept'); foreach ($this->map as $elements) { // Check if the current RequestMatcherInterface matches the current request if (!$elements[0]->matches($request)) { continue; } $options =& $elements[1]; // Do not reallow memory for this variable if (!empty($options['stop'])) { throw new StopFormatListenerException('Stopped format listener'); } if (empty($options['priorities']) && empty($priorities)) { if (!empty($options['fallback_format'])) { return new Accept($request->getMimeType($options['fallback_format'])); } continue; } if (isset($options['prefer_extension']) && $options['prefer_extension'] && !isset($extensionHeader)) { $extension = pathinfo($request->getPathInfo(), PATHINFO_EXTENSION); if (!empty($extension)) { // $extensionHeader will now be either a non empty string or an empty string $extensionHeader = $request->getMimeType($extension); if ($header && $extensionHeader) { $header .= ','; } $header .= $extensionHeader . '; q=' . $options['prefer_extension']; } } if ($header) { $mimeTypes = $this->normalizePriorities($request, empty($priorities) ? $options['priorities'] : $priorities); $mimeType = parent::getBest($header, $mimeTypes); if ($mimeType !== null) { return $mimeType; } } if (isset($options['fallback_format'])) { // if false === fallback_format then we fail here instead of considering more rules if (false === $options['fallback_format']) { return; } // stop looking at rules since we have a fallback defined return new Accept($request->getMimeType($options['fallback_format'])); } } }
public function parseParameters($value) { return parent::parseParameters($value); }
/** * Find the best Accept header depending of priorities. * * @param string $acceptRaw * @param array $priorities * * @return string|null */ private function getBestHeaderAccept($acceptRaw, array $priorities) { if (empty($acceptRaw)) { return; } try { $negotiaor = new Negotiator(); $accept = $negotiaor->getBest($acceptRaw, $priorities); } catch (InvalidArgument $e) { $accept = null; } if (is_null($accept)) { return; } return $accept->getValue(); }
<?php require 'vendor/autoload.php'; // Replace /comphppuebla/guzzle for the path to your negotiation.php file to try this route. // curl --header "Accept: application/xml" http://localhost/comphppuebla/guzzle/negotiation.php use Negotiation\Negotiator; use Faker\Factory; use Twig_Loader_Filesystem as FilesystemLoader; use Twig_Environment as Environment; $negotiator = new Negotiator(); $headers = getallheaders(); $format = $negotiator->getBest($headers['Accept']); $type = $format->getValue(); $template = 'contacts/show.json.twig'; if ('application/xml' === $type) { $template = 'contacts/show.xml.twig'; } $viewLoader = new FilesystemLoader('views'); $view = new Environment($viewLoader); $faker = Factory::create(); echo $view->render($template, ['contact' => ['contact_id' => $faker->randomDigit, 'name' => $faker->firstName, 'last_name' => $faker->lastName]]);
<?php require '../vendor/autoload.php'; use Negotiation\Negotiator; use Faker\Factory; use Slim\Slim; use Slim\Views\Twig; $app = new Slim(); $app->config('templates.path', '../views'); $app->view(new Twig()); $app->faker = Factory::create(); $contentNegotiation = function () use($app) { $negotiator = new Negotiator(); $format = $negotiator->getBest($app->request()->headers('Accept')); $type = $format->getValue(); $app->contentType($type); $app->template = 'contacts/show.json.twig'; if ('application/xml' === $type) { $app->template = 'contacts/show.xml.twig'; } }; $app->post('/contacts', $contentNegotiation, function () use($app) { $contactInformation = $app->request()->getBody(); parse_str($contactInformation, $contact); $contact['contact_id'] = $app->faker->randomDigit; //Simulate an insert $app->status(201); echo $app->render($app->template, ['contact' => $contact]); }); $app->get('/contacts/:id', $contentNegotiation, function ($id) use($app) { //This value should be specific to the current resource
/** * @expectedException Negotiation\Exception\InvalidMediaType */ public function testGetBestInvalidMediaType() { $header = 'sdlfkj20ff; wdf'; $priorities = array('foo/qwer'); $this->negotiator->getBest($header, $priorities, true); }
/** * Read the accept header and determine which media type we know about * is wanted. * * @param string $acceptHeader Accept header from request * @return string */ protected function determineMediaType($acceptHeader) { if (!empty($acceptHeader)) { $negotiator = new Negotiator(); $mediaType = $negotiator->getBest($acceptHeader, $this->knownMediaTypes); if ($mediaType) { return $mediaType->getValue(); } } return $this->getDefaultMediaType(); }