Question

I am trying to rewrite a url like http://example.com/extras/?cat=help&page=faq to something along the lines of http://example.com/extras/help/faq.

Well, rewrite as in a link or a user types the latter and the server understands that it's supposed to be the former. However, after implementing the rewrite that is ostensibly supposed to do what I want, navigating to pages results in a 403 code, because the server is taking what's in the URL bar literally. Because I have the server set up to disallow direct access to the subfolders, the 403 code is returned.

Below is the php code on my site that handles loading the pages to be included within the /extras index.php:

if(!empty($_GET['cat']) && !empty($_GET['page'])) {
  $folder = $_GET['cat'];
  $page = $_GET['page'] . '.php';
  $pages = scandir($folder);
  unset($pages[0], $pages[1]);

  $url .= $folder . DIRECTORY_SEPARATOR;

  if(file_exists($url . $page) && in_array($page, $pages)) {
    $url .= $page;
    include($url);
  } else {
    //Invalid category or page given
    header("HTTP/1.0 404 Not Found");
  }
} else {
  //No category or page given; fall back to contents
  include("contents.php");
}

The goal of the above file is for the contents of the subfile in the subfolders to be included in the body of index.php, not for the browser to actually try and navigate to the subfile.

This is (part of) the nginx config:

server {
  listen 80 default_server;
  listen [::]:80 ipv6only=on;

  root /usr/share/nginx/html;

  server_name localhost;

  error_page 403 /;
  error_page 404 /error/404.php;
  error_page 500 502 503 504 /error/50X.php;

  index index.html index.htm index.php;

  location / {
    try_files $uri $uri/ @no-extension;

    allow 192.168.0.0/24;
    allow 127.0.0.1;
    deny all;
  }

  location /help {
    try_files $uri $uri/ @help @no-extension;
  }

  location @help {
    rewrite "^/help/([^/]*)/([^/]*)$" /help/?cat=$1&page=$2 last;
  }

  location ~ /help/(help|otherfolder|morefolders) {
    deny all;
  }

  # PHP Handler
  location ~ \.php$ {
    try_files $uri $uri/ =404;

    include fastcgi_params;
    fastcgi_pass php5-fpm-sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_intercept_errors on;
  }

  location @no-extension {
    rewrite ^(.*)$ $1.php last;
  }
}

Any way to make the rewrite take effect instead of the browser trying to access a file it will never be able to?

Was it helpful?

Solution

while not exactly answering your question, would it not be simpler to

location /help {
    try_files $uri $uri/ /index.php;

when you load /help/faq/ its passed in REQUEST_URI to /index.php which does the subsequent regex split and file include...no need to rewrite. specific location blocks you want to restrict should be place above, so the deny will match first (if i recall correctly)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top