CodeIgniter nginx regras de reescrita para URLs do i8ln

1

Estou testando um site que é compilado com o CodeIgniter em uma caixa Vagrant de desenvolvimento (o Ubuntu TLS 14 com o nginx 1.8.1 e o PHP 5.6 com php-fpm) e o CodeIgniter parece falhar com nginx .

Depois de várias tentativas e erros e reunindo partes e peças de outros problemas semelhantes, consegui fazer um redirecionamento parcial. Este site tem estrutura de URL baseada em códigos ISO regionais como: http://example.com/REGION/language , então se eu estiver navegando pelo site dos EUA, ele redireciona para http://example.com/US/en e se Europa é% dehttp://example.com/EU/en. Existem pelo menos 4 a 5 dessas combinações usando o banco de dados GeoIP e os redirecionamentos do CodeIgniter 301.

Minha configuração nginx é a seguinte:

# Default server configuration
server {

    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {

        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
        #try_files $uri /index.html index.php =404;
        #try_files $uri $uri/ /index.php;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {

        # regex to split $uri to $fastcgi_script_name and $fastcgi_path
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # Check that the PHP script exists before passing it
        try_files $fastcgi_script_name =404;

        # Bypass the fact that try_files resets $fastcgi_path_info
        # see: http://trac.nginx.org/nginx/ticket/321
        set $path_info $fastcgi_path_info;
        fastcgi_param PATH_INFO $path_info;

        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;

        #FastCGI conf
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;

        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param REQUEST_URI $request_uri;
        fastcgi_param DOCUMENT_URI $document_uri;
        fastcgi_param DOCUMENT_ROOT $document_root;
        fastcgi_param SERVER_PROTOCOL $server_protocol;
        fastcgi_param HTTPS $https if_not_empty;

        fastcgi_param GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_param REMOTE_PORT $remote_port;
        fastcgi_param SERVER_ADDR $server_addr;
        fastcgi_param SERVER_PORT $server_port;
        fastcgi_param SERVER_NAME $server_name;

        # PHP only, required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param REDIRECT_STATUS 200;
    }

    # deny access to .htaccess files, if Apache's document root concurs with nginx's one
    location ~ /\.ht {
        deny all;
    }

    location /exmple {

        root /var/www/html/;
        index index.php;

        location ~ ^/example/(.+\.php)$ {

            client_max_body_size 4M;
            client_body_buffer_size 128k;
            root /var/www/html/;
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(.*)$;

            # With php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include /etc/nginx/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }

        location ~* ^/example/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)) {

            root /var/www/html/;
        }

        # CI rewrite rules
        if ($host ~* ^www\.(.*)) {

            set $host_without_www $1;
            rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
        }

        # Canonicalize codeigniter url end points and if your default controller is something other than "welcome" you should change the following
        if ($request_uri ~* ^(/pages(/view)?|/index(.php)?)/?$) {

            rewrite ^(.*)$ / permanent;
        }

        # removes trailing "index" from all controllers
        if ($request_uri ~* index/?$) {

            rewrite ^/(.*)/index/?$ /$1 permanent;
        }

        # removes trailing slashes (prevents SEO duplicate content issues)
        if (!-d $request_filename) {

            rewrite ^/(.+)/$ /$1 permanent;
        }

        # removes access to "system" folder, also allows a "System.php" controller
        if ($request_uri ~* ^/system) {

            rewrite ^/(.*)$ /index.php?/$1 last;
            break;
        }

        # unless the request is for a valid file (image, js, css, etc.), send to bootstrap
        if (!-e $request_filename) {

            rewrite ^/(.*)$ /index.php?/$1 last;
            break;
        }

        # catch all
        error_page 404 /index.php;
    }

}

Então, quando eu navego pelo localhost como http://192.168.33.15/example/ ele redireciona para http://192.168.33.15/example/INT/en , que é o padrão se um local válido não for encontrado no banco de dados GeoIP onde example é um subdiretório dentro do nginx raiz. Nenhum erro até aqui, mas o nginx não está sendo redirecionado corretamente e interpreta INT/en como pasta para que ele saia com um erro 404 Not Found .

Eu já passei por muitos posts no fórum aqui Serverfault , Stackexchange e outros recursos online, mas nenhum deles ajudou e já que não há muita documentação no CodeIgniter ou nginx sites ou isso parece ser o lugar certo para perguntar.

    
por anithegregorian 30.11.2016 / 13:33

1 resposta

0

Encontrou uma solução muito mais simples. Seguindo o que CodeIgniter faz nos bastidores para URLs limpos; no Apache, essa reescrita funciona enviando cada solicitação como http://example.com/index.php?/controller/method , que é então processada pelo CodeIgniter , portanto, o config.php deve se parecer com

$config['base_url'] = 'http://example.com'
$config['index_page'] = '';
$config['uri_protocol'] = 'REQUEST_URI';

Para conseguir o mesmo em nginx você teria que reescrever cada solicitação de maneira idêntica. Ajustei minha configuração do nginx com:

location /example {

    root /var/www/html/;
    index index.php;

    location ~ ^/example/(.+\.php)$ {

        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 4k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        root /var/www/html/;
        include /etc/nginx/snippets/fastcgi-php.conf;
    }

    location ~* ^/example/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)) {
        root /var/www/html/;
    }

    # Enforce SSL
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    # CI rewrite rules
    if ($host ~* ^www\.(.*)) {
        set $host_without_www $1;
        rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
    }

    if ($request_uri ~* ^(/example/(US|EU|INT)/(en|de)(.*))?$) {
        rewrite ^/(.*)$ /example/index.php?/$1 last;
    }

    if ($request_uri ~* ^(/example/(US|EU|INT)/(en|de)/(.*))?$) {
        rewrite ^/(.*)$ /example/index.php?/$1 last;
    }

    # catch all
    error_page 404 /index.php;
}

O link ausente existia em nginx regravar o log de depuração . Se você quiser saber sobre suas regras de reconfiguração e se elas correspondem ao seu conjunto de regras, adicione isso à configuração do nginx :

server{
  ...
  rewrite_log on;
  error_log /var/log/nginx/error.log info;
  ...
}

E o nginx fornecerá a você cada log de solicitação com uma correspondência ou não correspondência com o seu regex do PCRE. A partir daqui você pode ajustar sua configuração. Eu tive que prefixar o caminho (diretório) example no arquivo de configuração nginx para que as regras de reconfiguração funcionem como esperado.

    
por 02.12.2016 / 17:20