eRIZ 4 Zgłoś post Napisano Sierpień 18, 2011 (edytowany) Witam. Stawiam obecnie serwer na FreeBSD + nginx + php-fpm. I o ile wszystko działa OK, tak php-fpm sprawia mi problem, którego nie jestem w stanie rozwiązać. Mianowicie, workery są uruchamiane poprawnie. Jednak ni w ząb, nie da się do nich połączyć. W celu wykluczenia błędu w konfiguracji, uruchomiłem ręcznie interpreter jako responder na FastCGI działający na identycznym porcie i uprawnieniach, co w konfiguracji php-fpm. O dziwo, wszystko działa prawidłowo, więc konfiguracja serwera jest prawidłowa. Oto odpowiedź serwera w przypadku korzystania z php-fpm: HTTP/1.1 404 Not Found Server: nginx/1.0.5 Date: Thu, 18 Aug 2011 10:11:45 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive X-Powered-By: PHP/5.3.6 Natomiast ten sam skrypt wywołany przy responderze uruchomionym ręcznie działa bez zarzutu (w tym przypadku plik z wyłącznie phpinfo()). Macie jakieś pomysły? Kopię już drugi dzień w Google i konfiguracji; na IRC-ach głównych zainteresowanych nie dowiedziałem się, niestety, niczego... Edytowano Sierpień 18, 2011 przez eRIZ (zobacz historię edycji) Udostępnij ten post Link to postu Udostępnij na innych stronach
Kulfi 0 Zgłoś post Napisano Sierpień 18, 2011 pokaz konfiguracje nginx Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 18, 2011 http://wklej.org/hash/fdb9d6d2b09/ Udostępnij ten post Link to postu Udostępnij na innych stronach
elroy 6 Zgłoś post Napisano Sierpień 18, 2011 (edytowany) http://wklej.org/hash/fdb9d6d2b09/ Zastanawia mnie ten wpisu u Ciebie, fastcgi_param SCRIPT_FILENAME /tmp/index.php; w mojej konfiguracji wpis ten wygląda fastcgi_param SCRIPT_FILENAME /www/katalog_ze_stroną/$fastcgi_script_name; Edytowano Sierpień 18, 2011 przez elroy (zobacz historię edycji) Udostępnij ten post Link to postu Udostępnij na innych stronach
tym 205 Zgłoś post Napisano Sierpień 18, 2011 Jeśli jest w tmp to nie ma się co dziwić że sypie 404 Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 19, 2011 Zastanawia mnie ten wpisu u Ciebie, Podrzuciłem plik testowy, żeby wykluczyć problemy ze ścieżką. Jeśli jest w tmp to nie ma się co dziwić że sypie 404 Jakakolwiek ona nie jest - uprawnienia przestawiłem, z katalogu domowego jest to samo. Poza tym: W celu wykluczenia błędu w konfiguracji, uruchomiłem ręcznie interpreter jako responder na FastCGI działający na identycznym porcie i uprawnieniach, co w konfiguracji php-fpm. O dziwo, wszystko działa prawidłowo, więc konfiguracja serwera jest prawidłowa. Więc dlaczego via php-fpm miałoby nie działać? Udostępnij ten post Link to postu Udostępnij na innych stronach
blackfire 185 Zgłoś post Napisano Sierpień 19, 2011 Więc dlaczego via php-fpm miałoby nie działać? Bo to PHP Spróbuj pogmerać z cgi.fix_pathinfo w php.ini (w obie strony), ustaw SCRIPT_NAME (nie SCRIPT_FILENAME, to ma IIRC być pełną ścieżką do skryptu) na puste, $request_filename albo $fastcgi_script_name (testuj i FPM, i tradycyjne FastCGI). To tak na pałę, bo fpma nie miałem pod palcami (tzn. miałem dawno temu i zdążyłem zapomnieć). Jak nie pomoże to strace żeby ustalić co tak naprawdę idzie po drucie do PHP i gdzie ten PHP tego skryptu szuka. W sumie to może właśnie teraz masz taką kombinację subtelnych błędów w fastcgi_params i cgi.fix_pathinfo że standardowe SAPI FastCGI robi co trzeba (specyfikacja jest mętna więc o to wcale nietrudno żeby nap\w+dalać aż zadziała). A w FPM chcieli zrobić światu dobrze i zabili hacki. Mogło tak być, jakbym wprowadzał nowe SAPI to też pozabijałbym wszystkie hacki w starym -- migracja to dobry czas na takie zmiany Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 19, 2011 (edytowany) Już próbowałem wszystkiego - podsłuchałem ktracem, jak sobie nginx z php rozmawia i w obu przypadkach ścieżki w żądaniach są prawidłowe. Gdy wyłączę fix_pathinfo, wywala no input file specified. Gdy włączę - sytuacja jest taka, jak opisałem. Pogrzebałem trochę ktracem i wyniki są następujące. Dla php-fpm SCRIPT_FILENAME/sciezka/index.php QUERY_STRING REQUEST_METHODGET CONTENT_TYPE CONTENT_LENGTH SCRIPT_NAME/index.php REQUEST_URI/index.php DOCUMENT_URI/index.php DOCUMENT_ROOT/sciezka SERVER_PROTOCOLHTTP/1.1 GATEWAY_INTERFACECGI/1.1 SERVER_SOFTWAREnginx/1.0.5 i dla ręcznie spawnowanego FastCGI: SCRIPT_FILENAME/sciezka/index.php QUERY_STRING REQUEST_METHODGET CONTENT_TYPE CONTENT_LENGTH SCRIPT_NAME/index.php REQUEST_URI/index.php DOCUMENT_URI/index.php DOCUMENT_ROOT/sciezka SERVER_PROTOCOLHTTP/1.1 GATEWAY_INTERFACECGI/1.1 SERVER_SOFTWAREnginx/1.0.5 (wyciąłem nagłówki odpowiadające za porty i adresy IP komunikacji przeglądarki z serwerem; ścieżka oczywiście jest prawidłowa) Gdy wyłączę fix_pathinfo, zwraca no input file specified, gdy włączę, to pod php-fpm zwraca błąd przeglądarki. Edytowano Sierpień 19, 2011 przez eRIZ (zobacz historię edycji) Udostępnij ten post Link to postu Udostępnij na innych stronach
blackfire 185 Zgłoś post Napisano Sierpień 19, 2011 Gdy wyłączę fix_pathinfo, zwraca no input file specified, gdy włączę, to pod php-fpm zwraca błąd przeglądarki. A jak wyłączysz fix_pathinfo to stare SAPI FastCGI przestaje działać? Mam wrażenie że tak i że jak doprowadzisz je do działania z fix_pathinfo=0 to i FPM poleci. Sorry ale nie mam teraz opcji zagrzebać się we wnętrznościach PHP i szukać w kodzie co i jak. Może poszukaj w sapi/cgi/cgi_main.c co dokładnie robi fix_pathinfo i zrób to samo po stronie nginxa (siakieś REDIRECT_STATUS, SCRIPT_PATH_TRANSLATED i tego typu herezje). Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 19, 2011 (edytowany) A jak wyłączysz fix_pathinfo to stare SAPI FastCGI przestaje działać? Mam wrażenie że tak i że jak doprowadzisz je do działania z fix_pathinfo=0 to i FPM poleci. Działa bez najmniejszych problemów, niezależnie od tego ustawienia. A z php-fpm są cyrki... Może poszukaj w sapi/cgi/cgi_main.c co dokładnie robi fix_pathinfo i zrób to samo po stronie nginxa (siakieś REDIRECT_STATUS, SCRIPT_PATH_TRANSLATED i tego typu herezje). W źródłach nie grzebałem, ale kombinowałem z REDIRECT_STATUS i niestety, bez większych sukcesów. Skoro przy zwykłym FCGI działa niezależnie od fix_pathinfo, to chyba nie ma co grzebać w źródłach w tym celu... Edytowano Sierpień 19, 2011 przez eRIZ (zobacz historię edycji) Udostępnij ten post Link to postu Udostępnij na innych stronach
blackfire 185 Zgłoś post Napisano Sierpień 19, 2011 Skoro przy zwykłym FCGI działa niezależnie od fix_pathinfo, to chyba nie ma co grzebać w źródłach w tym celu... No to ćwiczenie dla czytelnika: czym się różni obsługa protokołu FastCGI w tych dwóch SAPI. Ja osobiście bym jednak w źródłach poszukał, są obrzydliwe ale siłą rzeczy najbardziej wiarygodne. Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 19, 2011 No właśnie kopię w źródłach i póki co, niczego niepokojącego nie widzę, zważywszy na to, że problem jest dość odosobniony... Wszelkie wskazówki mile widziane, bo w C wymiataczem nie jestem i coś mi może umknąć. Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 19, 2011 Znalazłem coś takiego: if (!ptr) { /* * if we stripped out all the '/' and still didn't find * a valid path... we will fail, badly. of course we would * have failed anyway... we output 'no input file' now. */ if (orig_script_filename) { _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME", orig_script_filename TSRMLS_CC); } script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", NULL TSRMLS_CC); SG(sapi_headers).http_response_code = 404; } Dobrze kopię? Udostępnij ten post Link to postu Udostępnij na innych stronach
blackfire 185 Zgłoś post Napisano Sierpień 19, 2011 Znalazłem coś takiego: if (!ptr) { /* * if we stripped out all the '/' and still didn't find * a valid path... we will fail, badly. of course we would * have failed anyway... we output 'no input file' now. */ if (orig_script_filename) { _sapi_cgibin_putenv("ORIG_SCRIPT_FILENAME", orig_script_filename TSRMLS_CC); } script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", NULL TSRMLS_CC); SG(sapi_headers).http_response_code = 404; } Dobrze kopię? Te okolice A na poziomie "tak ogólnie o co tu biega" to C i PHP są do siebie wystarczająco podobne żeby sobie poczytać bez konieczności wymiatania. Raczej nie znajdziesz wielkiego mrugającego neonu "o, tu robimy czary" ale jeżeli znajdziesz miejsce odpowiedzialne za wyserwowanie Twojego błędu (możliwe że to ten wklejony przez Ciebie kawałek) i przeanalizujesz, jak się tam znalazłeś to będziesz w domu Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 20, 2011 Kolejny dzień roztrzaskiwania mojego mózgu o dziwny problem. Do czego udało mi się dotrzeć. W pliku fpm_main.c jest odwołanie do: /* path_translated exists, we can continue ! */ if (php_fopen_primary_script(&file_handle TSRMLS_CC) == FAILURE) { Owszem, zwraca failure. Ale najciekawszy jest powód błędu: zlog(ZLOG_NOTICE, "WTF: %d", errno); zlog, to wbudowana funkcja do rzucania błędami do konsoli, jeśli php-fpm ma wyłączone w konfiguracji daemonize. Po wykonaniu żądania dla wyłączonego cgi.fix_pathinfo ta zmienna ma wartość errno = 2. Wyczytałem w Sieci, że taki kod jest zwracany, gdy poszukiwany plik nie istnieje (nie żaden brak uprawnień, czy coś; po prostu nie istnieje). Idąc dalej php_fopen_primary_script siedzi w fopen_wrappers.c i zwraca status FAILURE w kilku przypadkach. W moim przypadku sypie z tego powodu: if (filename) { resolved_path = zend_resolve_path(filename, strlen(filename) TSRMLS_CC); } resolved_path jest po prostu... puste. Co powoduje wysypanie następującego warunku: f (!resolved_path) { if (SG(request_info).path_translated != filename) { STR_FREE(filename); } /* we have to free SG(request_info).path_translated here because * php_destroy_request_info assumes that it will get * freed when the include_names hash is emptied, but * we're not adding it in this case */ STR_FREE(SG(request_info).path_translated); SG(request_info).path_translated = NULL; fprintf(stderr, "plecy3\n"); return FAILURE; } Dobierając się dalej: zend_resolve_path to tak naprawdę łańcuszek do php_resolve_path. Namierzyłem dziwny punkt: if ((*filename == '.' && (IS_SLASH(filename[1]) || ((filename[1] == '.') && IS_SLASH(filename[2])))) || IS_ABSOLUTE_PATH(filename, filename_length) || !path || !*path) { if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { return estrdup(resolved_path); } else { fprintf(stderr, "resolve plecy4: TSRM: %s, resolved_path: %s\n", tsrm_realpath(filename, resolved_path TSRMLS_CC), resolved_path); return NULL; } } Thread Safe Resource Manager - nie wiem, po kiego grzyba coś takiego, ale niech będzie; w pliku TSRM/tsrm_virtual_cwd.c siedzi to dziadostwo. Jest stałą debugująca, która pozwala na dumpowanie do stderr każdego etapu wyciągania. Po jej włączeniu i przekompilowaniu interpretera na starcie otrzymuję: cwd = path = /usr/local/sbin/php-fpm virtual_file_ex() = /root/php5.3-201108181230/sapi/fpm/php-fpm cwd = path = /usr/local/etc/php.ini virtual_file_ex() = /usr/local/etc/php.ini a dla plików puszczonych via FCGI: cwd = path = /sciezka/index.php Czyli powinno to coś działać. Ale nie działa. Funkcja tsrm_realpath stopuje na: if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { free(new_state.cwd); return NULL; } Tylko nie wiem, dlaczego... Przecież ścieżka jest prawidłowa i dostępna... Udostępnij ten post Link to postu Udostępnij na innych stronach
eRIZ 4 Zgłoś post Napisano Sierpień 22, 2011 Powiedzenie, że ilość kodu powodująca problem jest odwrotnie proporcjonalna do jego powagi jednak jest istotne. Znalazłem przyczynę - po 5 dniach walki i 3 grzebania w źródłach. Problemem był chroot i ścieżka bezwzględna jako SCRIPT_FILENAME miast względem chrootowanego katalogu. Dzięki za poświęcony czas. Udostępnij ten post Link to postu Udostępnij na innych stronach
crazyluki 114 Zgłoś post Napisano Sierpień 23, 2011 Brawo za wytrwałość;-) Udostępnij ten post Link to postu Udostępnij na innych stronach