2017-02-03 1 views
11

Mac의 MAMP PRO 설정에서 Symfony 앱을 실행 중입니다.Symfony의 ResponseListener가 dev 모드의 아파치에서 중복 된 헤더 'Content-Type'을 가져옵니다.

/** 
* Handle OPTIONS calls and add Access-Control headers. 
* 
* @param FilterResponseEvent $event Filter response event 
*/ 
public function onKernelResponse(FilterResponseEvent $event) 
{ 
    // Don't do anything if it's not the master request. 
    if (!$event->isMasterRequest()) { 
     return; 
    } 

    $request = $event->getRequest(); 
    if ($request->getRealMethod() == Request::METHOD_OPTIONS) { 
     $response = new Response(); 
     $response->headers->set('Access-Control-Allow-Origin', '*'); 
     $response->headers->set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, X-Auth-Token, X-App-Version, Content-Type, Accept, Authorization'); 
     $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT'); 
     $event->setResponse($response); 
    } else { 
     $response = $event->getResponse(); 

     $response->headers->set('Access-Control-Allow-Origin', '*'); 
     $response->headers->set('Access-Control-Allow-Credentials', true); 
     $response->headers->set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, X-Auth-Token, X-App-Version, Content-Type, Accept, Authorization'); 
     $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT'); 
    } 
} 

그것은 브라우저의 이온 응용 프로그램을 개발하고이 오류를받지 않고 응용 프로그램에서 호출 옵션을 처리하기 위해 단지 솔루션입니다 : 내 심포니 응용 프로그램 내에서 나는 다음과 같은 기능을 포함하는 ResponseListener를 사용합니다. 하지만 그것은 단지 예일뿐입니다. ResponseListener를 사용하는 다른 Symfony 앱에서도 동일한 문제가 있습니다.

오류가 발생하지 않으면 위의 예제는 prod 환경이나 dev 환경에서 실행하면 완벽하게 작동합니다. 그러나 최대한 빨리이 결과는 다음과 PHP 오류 얻을로 : 나는 apache_error.log로 보면

Internal Server Error 

The server encountered an internal error or misconfiguration and was unable to complete your request. 

Please contact the server administrator, [email protected] and inform them of the time the error occurred, and anything you might have done that may have caused the error. 

More information about this error may be available in the server error log. 

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request. 

는 말한다 :

FastCGI: comm with server "/Applications/MAMP/fcgi-bin/php7.0.13.fcgi" aborted: error parsing headers: duplicate header 'Content-Type', referer: http://app.domain/app_dev.php/my-route 

이는 PHP 오류를 발생하는 것입니다. 예를 들어, 내가하면 것은이 NotFoundHttpException

throw new NotFoundHttpException("Test exception"); 

와 나는 보통 심포니 오류 페이지를 얻을 던져.

나는

new ClassDoesNotExist(); 

는 내부 서버 오류가 발생 그런 짓을합니다.

내가 이런 함수의 위쪽에 exit;을 넣어 심포니 오류 페이지가 즉시 표시되기 때문에이 ResponseListener에 의한 것을 알고 다음 ResponseListener에 문제가

public function onKernelResponse(FilterResponseEvent $event) 
{ 
    exit; 

    // Don't do anything if it's not the master request. 
    if (!$event->isMasterRequest()) { 
     return; 
    } 
    ... 

있는가 ? 이 오류가 발생하지 않는 Apache에서 수행 할 수있는 일종의 구성이 있습니까?

편집 : 여기

MAMP PRO 가상 호스트 설정입니다 :

<VirtualHost *:80> 
ServerName project.localhost 

DocumentRoot "/Users/MyUser/Projekte/MyProject/web" 

<IfModule xsendfile_module> 
    XSendFilePath "/Users/MyUser/Projekte/MyProject/web" 
</IfModule> 

<Directory "/Users/MyUser/Projekte/MyProject/web"> 
    Options Includes FollowSymLinks ExecCGI 
    AllowOverride All 
    <IfModule authz_host_module> 
     Order allow,deny 
     Allow from all 
    </IfModule> 

</Directory> 

WSGIDaemonProcess project.localhost processes=2 threads=15 
WSGIProcessGroup project.localhost 
WSGIScriptAlias /project.localhostWsgiApp "/Users/MyUser/Projekte/MyProject/web/wsgiapp.py" 
AddHandler php-fastcgi .php 
Action php-fastcgi "/fcgi-bin/php7.0.13.fcgi" 

편집 2 : @mickadoo에 의해 제안

하는 또 다른 리스너가 추가되는 것을 가능 수는 중복 헤더 Content-Type. 전파를 멈 추면 내가 원하는 Symfony 오류 메시지가 나타납니다. 하지만 내 청취자도 처음으로 불려지므로 다른 청취자가 계속해서 방아쇠되는 것을 막을 수 있습니다. 다음에 debug:event-dispatcher 결과를 실행 : 나는 우선 순위 -2048과 다른 응답 리스너를 추가 할 때

"kernel.response" event 
----------------------- 

------- -------------------------------------------------------------------------------------------- ---------- 
Order Callable                      Priority 
------- -------------------------------------------------------------------------------------------- ---------- 
    #1  MyCompany\Bundle\AppBundle\EventListener\ResponseListener::onKernelResponse()     0 
    #2  Sonata\BlockBundle\Cache\HttpCacheHandler::onKernelResponse()        0 
    #3  Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse()    0 
    #4  Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector::onKernelResponse()  0 
    #5  Symfony\Component\Security\Http\RememberMe\ResponseListener::onKernelResponse()    0 
    #6  Sensio\Bundle\FrameworkExtraBundle\EventListener\HttpCacheListener::onKernelResponse()  0 
    #7  Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse()    -100 
    #8  Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse() -128 
    #9  Symfony\Component\HttpKernel\EventListener\SaveSessionListener::onKernelResponse()   -1000 
    #10  Symfony\Component\HttpKernel\EventListener\StreamedResponseListener::onKernelResponse()  -1024 
------- -------------------------------------------------------------------------------------------- -------- 

그 마지막 하나가 될 수 있도록 트리거가 다음과 같은 방법을 사용하십시오

/** 
* @param FilterResponseEvent $event Filter response event 
*/ 
public function onKernelResponse(FilterResponseEvent $event) 
{ 
    // Don't do anything if it's not the master request. 
    if (!$event->isMasterRequest()) { 
     return; 
    } 

    $response = $event->getResponse(); 

    echo "<pre>"; 
    print_r($response->headers->all()); 
    exit; 
} 

그것은 반환

Array 
(
    [cache-control] => Array 
    (
     [0] => no-cache, private 
    ) 
    [access-control-allow-origin] => Array 
    (
     [0] => * 
    ) 
    [access-control-allow-credentials] => Array 
    (
     [0] => 1 
    ) 
    [access-control-allow-headers] => Array 
    (
     [0] => Origin, X-Requested-With, X-Auth-Token, X-App-Version, Content-Type, Accept, Authorization 
    ) 
    [access-control-allow-methods] => Array 
    (
     [0] => POST, GET, PUT 
    ) 
    [content-type] => Array 
    (
     [0] => text/html; charset=UTF-8 
    ) 
    [x-debug-token] => Array 
    (
     [0] => 2f5dbb 
    ) 
    [x-debug-token-link] => Array 
    (
     [0] => http://app.project.localhost/app_dev.php/_profiler/2f5dbb 
    ) 
) 

그러나 추가로 Content-Type은 없습니다. 어떤 아이디어?내 방법의 끝에서 $event->stopPropagation()를 사용하고 0 모든 작품 우선 순위 (심포니 오류 페이지를 의미 리스너를 추가하는 경우 표시됩니다

:

편집 3 :

또 다른 이상한 점은 다음과 같다), 우선 순위 -2048으로 설정하면 아파치 오류 메시지가 나타납니다. 그러나 그것의 끝에 모든 헤더를 출력하더라도 중복 헤더가 없습니다. 나는 이것이 가능한 방법을 얻지 못한다. 어떻게 하나의 요청으로 아파치에 반환되는 동일한 헤더가 여러 개일 수 있으며 끝에있는 모든 헤더가 출력에서 ​​고유합니까?

+0

Apache VirtualHost 구성을 첨부 할 수 있습니까? – sentenza

+0

@ 센텐 자 MAMP PRO가 생성하는 가상 호스트 설정이지만, 원래의 질문에 변경하지 않았습니다. –

+1

Symfony 코드베이스를 지금 열어 보지 못했지만 어쩌면 헤더를 추가하는 다른 리스너 일 수도 있습니다. 리스너가 끝날 때'$ event-> stopPropagation()'을 시도 할 수 있습니다. – mickadoo

답변

2

이벤트에 대한 응답을 설정하는 방법은 어떻습니까?

$ event-> getResponse()에 의해 주어진 응답에서 헤더를 추가하지만 else 부분에서는 $ event-> setResponse ($ response)를 사용하지 않습니다.