3

I have special parameter data=/path/to/filename.htm in uri.

Its old and rusty site builded on SSI, and I can't modify it.

Problem is when filename passed as arg_data not exists, page is broken.

I want redirect to 404.htm in this case.

Something like that:

if (!-f $arg_data){
     rewrite ^.*$  /404.htm last;
   } 

But I get:

rewrite or internal redirection cycle while processing "/404.htm

I think its because I didn't check if arg_data exists.

But nginx have not nested if-s.

I tried:

set $data index.htm;                                                                                                                                               
if ($args ~ "data=(.+)") {                                                                                                                                         
    set $data $1;                                                                                                                                                  
}                                                                                                                                                                                                                                                                                                                                          
if (!-f $data) {                                                                                                                                                
    rewrite ^.*$  /404.htm last;                                                                                                                                   
}                   

Idea was set $data to some file which 100% exists, and after that rewrite if data param is passed.

For some reason its give the same error, internal redirection cycle

Looks like I do it in wrong way.

Korjavin Ivan
  • 2,250
  • 2
  • 26
  • 41

2 Answers2

3

OK, this is a very strange scenario, and you seem to be on the right track.

Instead of the rewrite, though, I would return 404; and use an error_page to define the 404 error page.

For example:

server {

    #...your other stuff...

    error_page 404 /404.htm;

    if (!-f $arg_data){
        return 404;
    }
}
Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
2

Ok, so regarding the last comments we had, you need an AND condition for two if statements.

NGinx is not able to do this.

To achieve this, we will use a little trick dealing with a $test var :

server {

  #...directives...

  error_page 404 /404.htm;

  if ($args != "") {                  # Test if there are some args       
     set $test A;
  }

  if (!-f /full/path/to/$arg_data) {  # Test if file in args doesn't exist
     set $test "${test}B";
  }

  if ($test = AB) {       # If there are some args AND if file doesn't exist
     return 404;
  }

}
krisFR
  • 13,280
  • 4
  • 36
  • 42