Назад | Перейти на главную страницу

Могут ли блоки местоположения nginx соответствовать строке запроса URL?

Жестяная банка nginx location блоки соответствует строке запроса URL?

Например, какой блок местоположения может соответствовать HTTP GET запрос

GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1

Могут ли блоки местоположения nginx соответствовать строке запроса URL?

Короткий ответ: Нет.

Длинный ответ: Есть обходной путь, если у нас есть только несколько таких блоков местоположения.

Вот пример обходного пути для 3 блоков местоположения, которые должны соответствовать определенным строкам запроса:

server {
  #... common definitions such as server, root

  location / {
    error_page 418 = @queryone;
    error_page 419 = @querytwo;
    error_page 420 = @querythree;

    if ( $query_string = "service=git-receive-pack" ) { return 418; }
    if ( $args ~ "service=git-upload-pack" ) { return 419; }
    if ( $arg_somerandomfield = "somerandomvaluetomatch" ) { return 420; }

    # do the remaining stuff
    # ex: try_files $uri =404;

  }

  location @queryone {
    # do stuff when queryone matches
  }

  location @querytwo {
    # do stuff when querytwo matches
  }

  location @querythree {
    # do stuff when querythree matches
  }
}

Вы можете использовать $ query_string, $ args или $ arg_fieldname. Все сделают свою работу. Вы можете узнать больше о error_page в официальных документах.

Предупреждение: пожалуйста, убедитесь не использовать стандартные коды HTTP.

Я знаю, что этому вопросу больше года, но я провел последние несколько дней, разрушая свой мозг из-за аналогичной проблемы. Мне нужны были разные правила аутентификации и обработки для публичных и частных репозиториев, включая отправку и извлечение. Это то, что я наконец придумал, поэтому решил поделиться. Я знаю if - сложная директива, но, похоже, она мне подходит:

# pattern for all repos, public or private, followed by username and reponame
location ~ ^(?:\/(private))?\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?$ {

    # if this is a pull request
    if ( $arg_service = "git-upload-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /upload$uri;

    }

    # if this is a push request
    if ( $arg_service = "git-receive-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /receive$uri;

    }

}

# for pulling public repos
location ~ ^\/upload(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing public repos
location ~ ^\/receive(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pulling private repos
location ~ ^\/upload\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing private repos
location ~ ^\/receive\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

Есть другой способ сделать это, если вы используете nginx в качестве прокси.

установить переменную в серверном блоке:

set $nocache="0";

Внутри блока местоположения добавьте if:

if ( $arg_<query string to match> = "<query string value>") { set $nocache "1"; }

И добавьте две новые директивы прокси:

proxy_cache_bypass $nocache ;
proxy_no_cache $nocache ;

он всегда будет перенаправлять на вышестоящий сервер без кеша