4

I have done a load of searching for an answer for this and I cannot find a suitable answer.

Basically, I have a site built in SilverStripe running on NGINX. It all works pretty well, but I want any files/images uploaded via the admin (to the assets folder) to be resolved via index.php in the site root (so we can check permissions of the files set in the admin before returning them to the user).

I have a pretty simple nginx config (for my local docker instance):

server {
  include mime.types;
  default_type  application/octet-stream;
  client_max_body_size 0;
  listen 80;
  root /var/www/html;

  location / {
      try_files $uri /index.php?$query_string;
  }

  location ^~ /assets/ {
      try_files $uri /index.php?$query_string;
  }

  location /index.php {
    fastcgi_buffer_size 32k;
    fastcgi_busy_buffers_size 64k;
    fastcgi_buffers 4 32k;
    fastcgi_keep_conn on;
    fastcgi_pass   php:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
  }
}

The issue is the lines:

  location ^~ /assets/ {
      try_files $uri /index.php?$query_string;
  }

Unfortunately try_files checks for a file's existence before handing the request over to php. Is there a way to stop this and hand all requests from the assets directory directly to PHP?

PsychoMo
  • 699
  • 5
  • 17
  • 1
    Try removing `$uri` so it doesn't look for it. Though I'm not sure just `$query_string` is going to help did you mean to pass the $uri as a GET param to PHP? – Jonnix Mar 20 '19 at 22:32
  • I did try this, but as the answer below states, try_files needs two parameters. I did manage to fudge it by using `try_files /index.php?$query_string /index.php?$query_string;` – PsychoMo Mar 21 '19 at 12:05

2 Answers2

2

try_files needs two parameters, so you could use a dummy value to replace the file term. For example:

try_files nonexistent /index.php$is_args$args;

See this document for details.


But the neater solution is probably a rewrite...last statement:

rewrite ^ /index.php last;

The rewrite directive will automatically append the query string. See this document for details.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • PERFECT! The rewrite works like a charm. I did think that `rewrite` could be the answer, I didn't realise the query string was automatically appended. – PsychoMo Mar 21 '19 at 12:08
1

In my opinion just blindly passing everything to the proper script is the right(TM) thing to do.

location /assets/ {
    include       fastcgi_params;
    fastcgi_param SCRIPT_NAME /index.php;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_pass  php:9000;
}
ntd
  • 7,372
  • 1
  • 27
  • 44