Почему CGI :: cookie в Perl может устанавливать cookie в IE, а не в Firefox? - PullRequest
5 голосов
/ 26 октября 2010

У меня есть немного кода Perl CGI, который я пытаюсь запустить в веб-пространстве проекта учетной записи SourceForge. Код может отлично установить cookie браузера при общении с IE, но файл cookie не установлен при обращении к Firefox. Когда я тестирую с Apache на "localhost", оба браузера работают нормально. Firefox исключает только URL-адрес удаленного SourceForge.

Поиск выявил десятки почти дублирующих вопросов, но обычно у людей возникает прямо противоположная проблема! (Firefox в порядке и IE имеет проблему)

Вот вспомогательная утилита, которую я вызываю, чтобы установить куки:

sub setCookie {
    my $name = shift;
    my $value = shift;
    my $expires = shift;
    my $path = shift;
    my $domain = shift;
    if( !defined( $expires ) ) {
        $expires = '+4h';
    }
    if( !defined( $path ) ) {
        $path = '/';
    }
    if( !defined( $domain ) ) {
        $domain = 'steveperkins.sourceforge.net';
    }
    my $cookie = CGI::cookie(
        -name    => $name,
        -value   => $value,
        -domain   => $domain,
        -expies => $expires,
        -path    => $path
    );
    $r->header_out('Set-cookie' => $cookie);
}

Есть идеи? Моей первой мыслью была какая-то проблема субдомена, потому что в URL моего проекта SourceForge есть субдомен, а в «localhost» - нет. Я экспериментировал с настройкой домена cookie для моего конкретного субдомена или только для базы «sourceforge.net». Кажется, это не имеет значения в любом случае.

ОБНОВЛЕНИЕ: Кто-то в комментариях ниже спросил о заголовках ответа HTTP. Я использовал инструмент анализатора сетевого трафика Wireshark для мониторинга заголовков запросов и ответов для IE и Firefox, и вот как они выглядят:

IE (работает)

Запрос

GET http://myproject.sourceforge.net/cgi-bin/myscript.cgi?page=user&userID=1 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Referer: http://myproject.sourceforge.net/cgi-bin/myscript.cgi
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; InfoPath.1; .NET CLR 3.0.30618)
Proxy-Connection: Keep-Alive
Host: myproject.sourceforge.net
Authorization: Basic [password omitted]

Ответ

HTTP/1.1 200 OK
Server: nginx/0.7.63
Date: Tue, 26 Oct 2010 18:23:49 GMT
Content-Type: text/html; charset=ISO-8859-1
Expires: Thu, 28 Oct 2010 18:23:49 GMT
Cache-Control: max-age=172800, proxy-revalidate
Transfer-Encoding: chunked
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Content-Encoding: gzip
Set-Cookie: USER=1; domain=myproject.sourceforge.net; path=/

Firefox (не работает)

Запрос

GET http://myproject.sourceforge.net/cgi-bin/myscript.cgi HTTP/1.1
Host: myproject.sourceforge.net
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Proxy-Connection: keep-alive
Cookie: __utma=191645736.1501259260.1287701281.1288028150.1288100562.10; __utmz=191645736.1288101011.10.10.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=sourceforge%20project%20web%20space%20basic%20auth; _jsuid=4215309712123065236
Authorization: Basic [password omitted]

Ответ

HTTP/1.1 200 OK
Server: nginx/0.7.63
Date: Tue, 26 Oct 2010 18:17:58 GMT
Content-Type: text/html; charset=ISO-8859-1
Expires: Thu, 28 Oct 2010 18:17:58 GMT
Cache-Control: max-age=172800, proxy-revalidate
Transfer-Encoding: chunked
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Content-Encoding: gzip
Age: 0

Ответы [ 2 ]

5 голосов
/ 26 октября 2010

Я бы сказал, что у вас есть ошибка в настройке срока действия

if( !defined( $path ) ) {
    $expires = '/';
}

должно быть

if( !defined( $path ) ) {
    $path = '/';
}

Обновлено: На основе информации, которую выприведите выше, используя wireshark. Я бы проверил, действительно ли setCookie вызывается при входе в Firefox (кстати, оба URL разные, это может указывать на то, что логика в вашем коде пропускает вызов setCookie на основе URL).Также попробуйте использовать один и тот же URL с обоими браузерами и посмотрите, что произойдет.

2 голосов
/ 27 октября 2010

Argh! Оказывается, проблема заключается в том, что при запуске на "localhost" в игре присутствует только один cookie, но при размещении на серверах SourceForge существует несколько cookie-файлов.

Если вы посмотрите на заголовки запросов Firefox, вырезанные из вставленного в предыдущем вопросе заголовка, вы заметите, что есть несколько пар имя-значение cookie ... каждая пара разделяется точкой с запятой. Мой код не смог учесть это , поэтому все, что он увидел, это один гигантский испорченный файл cookie.

Я все еще не уверен на 100%, почему он частично работал в IE, и я могу вернуться к этому в будущем, чтобы узнать, можно ли узнать больше. Но это в основном спорный вопрос на данный момент. Я изменил код, разделив его на точки с запятой, а затем разделив его на знаки равенства, теперь я отлично обрабатываю файлы cookie.

Спасибо всем за понимание и предложения! Пьер-Люк, я высказал ваш ответ из благодарности за все комментарии под ним.

    sub getCookie {
    my $cookieName = shift;
    my %headers = $r->headers_in;
    my @keys = keys( %headers );
    foreach my $name ( @keys ) {
        if( $name eq 'Cookie') {
        my @semicolontokens = split( ';', $headers{$name} );
        foreach my $splitname ( @semicolontokens ) {
           $splitname =~ s/^\s+//;
           $splitname =~ s/\s+$//;
           my @pair = split( '=', $splitname );
               if( $pair[0] eq $cookieName ) {
               return $pair[1];
               }
           }
       }
   }
...