Русские буквы в URL, IE7 - адреса UTF-8 - 404.

Pavel V. pavel2000 at ngs.ru
Thu Aug 30 21:02:33 MSD 2007


Здравствуйте, Nginx-RU.

После того, как вышел IE 7 и пользователи начали на него постепенно
переходить, стала все чаще и чаще возникать следующая жалоба от
пользователей - 404 при попытке скачать файлы с русскими буквами в
ссылке. Имена файлов на диске, локаль на сервере - CP1251. Файлы
раздаются естественно Nginx-ом.

Все дело в том, что в Internet Explorer поставлена галка "Отправить URL-адреса UTF-8"
(найти её можно: "Свойства обозревателя" -> "Дополнительно" - "Международный" -> "Отправить URL-адреса UTF-8")
и браузер теперь шлет запрос на файл, который сервером найтись не может.

Для решения данной проблемы со скачиванием файлов сейчас мы
просто рекомендуем убирать эту галку, но, как все понимают, это не выход.

Пример запроса:

обычный браузер:
217.xx.80.58 - - [30/Mar/2007:13:57:46 +0700] "GET /Others/\xd1\xe1\xee\xf0\xed\xe8\xea\xe8/2006/2006%20Ministry%20of%20Sound%20Housexy%20Spring%202006%20(CD%2002)/13-DJ%20Meri--Not%20a%20Dream%20(Paul%20Harris%20Vocal%20Mix).mp3 HTTP/1.0" 200 9193720

IE 7.0:
217.xx.80.58 - - [30/Mar/2007:13:56:47 +0700] "GET /Others/%D0%A1%D0%B1%D0%BE%D1%80%D0%BD%D0%B8%D0%BA%D0%B8/2006/2006%20Ministry%20of%20Sound%20Housexy%20Spring%202006%20(CD%2002)/13-DJ%20Meri--Not%20a%20Dream%20(Paul%20Harris%20Vocal%20Mix).mp3 HTTP/1.0" 404 329

В этих примерах куски "\xd1\xe1\xee\xf0\xed\xe8\xea\xe8"
"%D0%A1%D0%B1%D0%BE%D1%80%D0%BD%D0%B8%D0%BA%D0%B8" представляют собой
слово  "Сборники" в виде байтов CP1251 и UTF-8. 

Менять структуру каталогов, переименовывать русские имена файлов - не
хочется. Хочется сделать перекодировку запроса "на лету", например
используя возможности ngx_http_perl_module.

Только как это реализовать - пока мне не очень ясно, потому и прошу
Вашей помощи. Раздача файлов идет _преимущественно_ по отдельному
порту, раздаются как mp3, так и avi/mpg/...

Схематически я представляю себе это в следующем виде:

http {

    perl_modules  perl/lib;
    perl_require  myhello.pm;

  server {
        location / {
            root .... ;
            perl  myhello::handler;
        }

        location /decoded/ {
            root .... ;
            internal;
        }
  }
}

package myhello;
use nginx;

sub myUTFdecode {
    $var = shift;
    ...
    return $var;
}

>первый вариант:

sub handler {
    my $r = shift;

    if ($r->request_method ne "GET") {
        return HTTP_BAD_REQUEST;
    }
    
    $r->send_http_header('audio/mpeg');  // какой тип отправлять ??
    $r->allow_ranges();
    //нужны ли дополнительные заголовки ?
    $r->sendfile(myUTFdecode($r->filename));
    
    return OK;
}
1;
__END__

>либо, второй вариант:

sub handler {
     my $r = shift;
     $r->internal_redirect("/decoded/".myUTFdecode($r->filename));
     return OK;
}

Это мои наброски, перл в Nginx я еще ни разу не использовал.
Заранее благодарен за все советы и подсказки путей решения задачи.

-- 
С уважением,
 Pavel                          mailto:pavel2000 at ngs.ru






More information about the nginx-ru mailing list