Search code examples
phpzend-framework2laminas-api-toolscontent-negotiation

How to make Zf2 Apigilty accept client request with no Accept set in header


Recently I have upgraded my rest server to Zf2 Apigility, which the content negotiation settings are as follows,

'zf-content-negotiation' => array(
    'controllers' => array(
        'CloudSchoolBusFileApi\\V1\\Rest\\FileReceiver\\Controller' => 'Json',
    ),
    'accept_whitelist' => array(
        'CloudSchoolBusFileApi\\V1\\Rest\\FileReceiver\\Controller' => array(
            0 => 'application/vnd.cloud-school-bus-file-api.v1+json',
            1 => 'application/json',
        ),
    ),
    'content_type_whitelist' => array(
        'CloudSchoolBusFileApi\\V1\\Rest\\FileReceiver\\Controller' => array(
            0 => 'application/vnd.cloud-school-bus-file-api.v1+json',
            1 => 'application/json',
            2 => 'multipart/form-data',
        ),
    ),

The problem is that my client(mobie app) has already deployed and the they send post requests with no Accept field setting in the http header. so I always got following 406 error from the server,

[Response] => Array
(
    [statusCode] => 406
    [content] => {"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Not Acceptable","status":406,"detail":"Cannot honor Accept type specified"}
 )

So anyone has an idea of how to let the server accept such request from client with no Accept in header?


Solution

  • You could write a listener in which you check the Accept header of the incoming request. If no Accept header is set you can add an Accept header with a default value; for example application/json.

    So something like:

    /**
     * Set empty accept header by default to `application/json`
     *
     * @param MvcEvent $event
     * @return void|ApiProblemResponse
     */
    public function onRoute(MvcEvent $event)
    {
        $request = $event->getRequest();
        $headers = $request->getHeaders();
    
        if($headers->has('Accept')){
            // Accept header present, nothing to do
            return;
        }
    
        $headers->addHeaderLine('Accept', 'application/json');
    }
    

    Better would of course be to update your client.