Pull to refresh

Comments 13

IP адрес, как вы знаете, состоит из 4 байт (октетов). Всего 32 бита. Подсеть можно указывать в 2 форматах:
как маску вида 255.255.255.0
(можно записать в бинарном виде 11111111 11111111 11111111 00000000)
или как количество бит в маске, установленных в единицу: /24

Соответственно, чтобы проверить, что IP адрес попадает в подсеть, достаточно сделать побитовое логическое И адреса и маски, если получится адрес подсети — то адрес в ней находится. Пример:
подсеть 192.168.10.0/24
адрес 192.168.10.87
умножаем его на 255.255.255.0
получаем 192.168.10.0 — он в подсети

Таким образом получить из 192.168.10.0/24 начало и конец диапазона элементарно: начало диапазона совпадает с собственно адресом, сети, а чтобы вычислить конец — надо прибавить инвертированную маску: для 255.255.255.0 это будет 0.0.0.255
то есть 192.168.10.0/24 соответствует диапазону 192.168.10.0 — 192.168.10.255

Очевидно, что не всегда получится сделать обратную операцию. Для этого необходимо из конечного адреса диапазона вычесть начальный, получившаяся цифра должна быть на единичку меньше какой-либо степени двойки. Если является — то надо из 11111111 11111111 11111111 11111111 вычесть ту самую цифру, оставшееся и есть маска.
проблемка была еще и в том, что в одном диапазоне может находиться несколько подсетей, все-еще толком не разобрался как считать
А куда у вас попадают поисковые роботы?
Вообще как такое решение может повлиять на индексацию сайта яндексом и гуглом, кто нибудь в курсе?
Редирект происходит только при заходе на главную. Главная страница априори не содержит никакой интересной для индексации информации, так как это набор ссылок на статьи, которые, к тому же, повторяются на региональных страницах. Как-то так, хотя могу и ошибаться.
Извините, но ваш конфиг nginx просто ужасен
# установили переменную $get_redirect со значением donot_redirect
set $get_redirect donot_redirect; 
# в случае, если клиент заходит на главную страницу присваеваем переменной значение do_redirect                             
if ($uri = '/') {                                               
    set $get_redirect do_redirect;                              
} 
# если nginx не нашел адреса клиента в базе и в переменной $region_number значение 'all' , то и редиректить незачем                                                           
if ($city = 'all') {                                            
    set $get_redirect donot_redirect;                           
}  
# если уже есть кука, т.е. клиент уже заходил к нам и мы его редиректили на его регион (должна же быть возможность смотреть главную страницу)                                                             
if ($cookie_geolocate = 1) {                                    
    set $get_redirect donot_redirect;                           
} 
# ну и собственно сам редирект на нужную страницу                                                              
if ($get_redirect = do_redirect) {                                          
    rewrite ^(.*)$ http://example.com/region/$region_number redirect;    
}    

location / {
    if ($cookie_geolocate = 1) {
        break;
    }
    if ($region_number != all) {
        return http://example.com/region/$region_number;
    }
}
Я, пожалуй, даже поясню несколько моментов.

  1. Наличие if ($uri ...) — первый признак плохой конфигурации. То, что так можно писать, не значит, что так нужно писать. Директива location не только структурирует вашу конфигурацию, но и специально оптимизирована для поиска конфигурации по URI. Если это не регулярное выражение, то поиск будет происходить по дереву. Не нужно программировать на if-ах, количество директив модуля rewrite должно быть сведено к минимому.
  2. У вас поиск по «базе» будет происходить на каждый (!) запрос — пустая трата ресурсов когда URI заведомо не "/" или установлена кука.
  3. rewrite ^(.*)$ — просто пустая трата памяти и ресурсов процессора на бессмысленное регулярное выражение с захватом.
Зашел сюда написать примерно такой же комментарий, но Вы уже успели.

И правда, очередная каша из if, идущих подряд. Действительно, «уж сколько раз твердили миру», но «программисты на конфигах nginx» не переводятся. Про директиву map, например, в очередной раз, видимо, не дочитали. А ведь частенько ей одной можно убрать две трети этих if'ов…
Типа так просто, информация к размышлению. Набросал в 5:45 утра местного времени.
Для статики работать должно. Для динамики надо прописать одинаковые proxy_pass в два последних location'а

Кстати, не до конца и «красиво», есть один нюанс — когда геолокейшн не подберет региона, то будет открываться будет урл /region/all

Но повторюсь, 6 утра местного и будем считать, что я оставляю этот нюанс в качестве домашнего задания желающим отполировать.

geo $city {
    default all;
    # a.b.c.d       region1;
    # z.y.x.w       region2;
}

map $cookie_geolocate $destlocation {
    default redir;
    0       redir;
    1       all;
}

server  {

    root /var/www;

    location @all {
        # default root
    }

    location @redir {
        rewrite /           /region/$city redirect;
    }

    location = / {
        error_page 418 = @$destlocation;
        return 418;
    }

    location /region/all {
        alias /var/www;
    }

    location / {
        # default root
        add_header Set-Cookie "geolocate=1;Path=/;";
    }

}
Не бейте палками, пост возник, в части своей, из-за того что с nginx на ВЫ(иначе я бы просто знал про эту возможность). Кстати, есть где-нибудь литература в которой можно прочитать про тонкости использования if в конфигах nginx? Администрированием сервера занимаются администраторы, но, учитывая что в данном случае мы попадаем на ту самую грань разделения администратора и программера, вот и написал что смог, читая api nginx
Да мы лично Вас палками не бьем, поймите правильно. Скорее, беспокоимся, чтобы потом это не начали копипастить, не глядя. Как часто бывает.

wiki.nginx.org/IfIsEvil
Vbart и cadmi — спасибо. Передам админам сервера. У нас битва за оптимизацию нагрузки идет не первый год. Понимаю что и они не гуру и мы, программеры им забот добавляем, но факт в том, что задачи всегда ставит «заказчик», а вот реализация зависит от навыков… (на приобретение коих, навыков, «заказчик» никогда не хочет тратить время)
Sign up to leave a comment.

Articles