1

I implemented a location configuration like this (legituser is set by a map lookup):

location / {
  if ($legituser = 0) {
    return 200 "you are not allowed to access this url, please do bla bla bla ...";
  }

  more_set_headers "Content-Type: $arg_mimetype";

  root /media/s3content;
  try_files $uri $uri/ =404;
}

Remark: I know that http status might seem odd in this scenario but I want to make sure the users get proper information and in the real scenario the return contains much more than shown here.

If the user is legit, I want to return files that are stored on S3. The Content-Type needs to be overwritten by the value of ...?mimetype=... which I do by using more_set_headers.

This works quite well, except when I'm not legit and open for example http://server/some/path/somefile?mimetype=image/png. Then I get a png file which consists of only the text sent by return. It became clear to me that return doesn't work like return in a programming language like Java and doesn't exit the location block.

In a programming language I would do something like this:

if( legituser == 0 ) {
  setMimeType( "text/html" );
  return( 200, "you are not ..." );
} else {
  setMimeType( $arg_mimetype );
  try_files ...
}

But this is not how nginx works and I'm absolutely not sure if I'm running into the usual problem if using if in a evil way.

Would this work and be "OK" / proper style ?

set $ct $arg_mimetype;

if( $legituser = 0 ) {
  set $ct 'text/html';
}

more_set_headers "Content-Type: $ct";

if( $legituser = 0 ) {
  return 200 "you are not ...";
}

root /media/s3content;
try_files $uri $uri/ =404;
1
  • From your link, "would it be 'OK'" block is evil. It says the only thing you can do in an if is return or rewrite and you do a set. Commented Aug 4, 2021 at 19:04

1 Answer 1

1

From How can I add header conditionally in nginx configuration? on StackOverflow this should be:

map $legituser $mimetypeheadervalue {
    0        'text/html';
    default  $arg_mimetype;
}

location / {

  more_set_headers "Content-Type: $mimetypeheadervalue";

  if ($legituser = 0) {
    return 200 "you are not allowed to access this url, please do bla bla bla ...";
  }

  root /media/s3content;
  try_files $uri $uri/ =404;
}

In the map, if the $legituser is zero it uses text/html and otherwise fills in with the value in your other variable. Then you use the newly created variable from your map to set the header.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.