Здравствуйте, подскажите в чем проблема. Недавно начал изучать перл, и задался целью написать скрипт авторизации на MAIL.ru вот код Code: #!/usr/bin/perl use IO::Socket; use strict; my $login = "Логин"; my $domain = "mail.ru"; my $password = "пароль"; #STEP 1 my $hostname = "win.mail.ru"; my $path = "/cgi-bin/login"; my $sock = new IO::Socket::INET(PeerAddr =>$hostname,PeerPort => 80,PeerProto => 'tcp',TimeOut => 5); my $headers = "GET $path HTTP/1.0\r\n"; $headers .= "Host: $hostname\r\n"; $headers .= "Connection: keep-alive\r\n\r\n"; my $answ; print $sock $headers; sysread( $sock, $answ, 4096); my $mrcu = ''; $answ=~ s/\w{28}/$mrcu=$&/gime; close $sock; #STEP 2 $path = "/cgi-bin/auth"; $sock = new IO::Socket::INET(PeerAddr =>$hostname,PeerPort => 80,PeerProto => 'tcp',TimeOut => 5); my $data = "page=&post=&login_from=&Login=$login&Domain=$domain&Password=$password&\r\n\r\n"; $headers = "POST $path HTTP/1.0\r\n"; $headers .= "Host: $hostname\r\n"; $headers .= "Content-type: application/x-www-form-urlencoded\r\n"; $headers .= "Content-Length: ".length($data)."\r\n"; $headers .= "Cookie: mrcu=$mrcu\r\n"; $headers .= "Connection: Close\r\n\r\n"; print $sock ($headers.$data); sysread( $sock, my $answ, 4096); my ($mpop, $t, $location) = ''; $answ=~ s/\w{10}\:\S*/$mpop=$&/gime;chop $mpop;$answ=~ s/\w{10}\:\S*//gim; $answ=~ s/(\w{88})/$t=$&/gime; $mpop=~ s/\:\S{98}/$location=$&/gime; $location=~ s/\://gim;$location="http://win.mail.ru/cgi-bin/checkcookie?id=".$location; close $sock; #STEP 3 $sock = new IO::Socket::INET(PeerAddr =>$hostname,PeerPort => 80,PeerProto => 'tcp',TimeOut => 5); $headers = "GET $location HTTP/1.1\r\n"; $headers .= "Host: $hostname\r\n"; $headers .= "Content-type: application/x-www-form-urlencoded\r\n"; $headers .= "Cookie: mrcu=$mrcu; Mpop=$mpop; t=$t]\r\n"; $headers .= "Connection: keep-alive\r\n\r\n"; print $sock ($headers.$data); sysread( $sock, my $answ, 4096); close $sock; #STEP 4 $hostname = "win.mail.ru"; $path = "http://win.mail.ru/cgi-bin/start?back=1"; $sock = new IO::Socket::INET(PeerAddr =>$hostname,PeerPort => 80,PeerProto => 'tcp',TimeOut => 20); $headers = "GET $path HTTP/1.1\r\n"; $headers .= "Host: $hostname\r\n"; $headers .= "Content-type: application/x-www-form-urlencoded\r\n"; $headers .= "Accept-Language: ru-RU,ru;q=0.9,en;q=0.8\r\n"; $headers .= "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n"; $headers .= "Cookie: mrcu=$mrcu; Mpop=$mpop; t=$t\r\n"; $headers .= "Connection: keep-alive\r\n\r\n"; print $sock ($headers.$data); sysread( $sock, my $main, 80000); print $main; Авторизация, как я понял, проходит в 4 этапа: 1)при входе на сайт нам дают "печеньку" $mrcu 2)потом идет авторизация, и нам дают еще $mpop и $t 3)идет редирект на проверку кукисов 4)сам вход на мейл проблема заключаеться в том, что после 4го шага скрипт не грузит полность страничку, а только заголовки+1 ява скрипт подскажите что не так и поправьте код пожалуйста
сервер выдает Code: HTTP/1.1 200 OK Server: nginx/0.7.41 Date: Fri, 17 Apr 2009 15:50:28 GMT Content-Type: text/html; charset=windows-1251 Connection: keep-alive Cache-Control: no-cache,no-store,must-revalidate Pragma: no-cache Expires: Thu, 17 Apr 2008 15:50:28 GMT Last- Modified: Fri, 17 Apr 2009 19:50:28 GMT Content- Length: 75712
могу предположить следующее.... recv не обязательно получает указаное количество байт... тоесть вся страница приходит в разных покетах вот пример реализации "правильной" функции получения и отправки данных на Си Code: int sendall(SOCKET s, char *buf, int len, int flags) { int total = 0; int n; while(total < len) { n = send(s, buf+total, len-total, flags); if(n == -1) { break; } total += n; } return (n==-1 ? -1 : total); } // принять ВСЕ ... - правильная функция int recvall(SOCKET s, char *buf, int len, int flags) { int total = 0; int n; while(total < len) { n = recv(s, buf+total, len-total, flags); if(n == -1) { break; } total += n; } return (n==-1 ? -1 : total); } на PERL давно не писал, но если сам не сможешь помогу перевести код
Code: use warnings; use IO::Socket; $|=1; my $login = "login"; my $domain = "mail.ru"; my $password = "pass"; my $answ1 = req('win.mail.ru', '/cgi-bin/auth', 'POST', "Login=$login&Domain=$domain&Password=$password", 0); my $ck1 = collect($answ1); $answ1 =~ /<HTML>http:\/\/win.mail.ru(.+?)<\/HTML>/; req('win.mail.ru', $1, 'GET', 0, $ck1); my $answ2 = req('win.mail.ru', '/cgi-bin/start?back=1', 'GET', 0, $ck1); print $answ2; sub collect { my $data = $_[0]; my $cookie = undef; while($data =~ /Set-Cookie: (.+?)(;|\r)/igs) { $cookie .= $1."; "; } return $cookie; } sub req { my($host, $path, $type, $data, $cookies) = @_; my $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => 80, PeerProto => 'tcp', TimeOut => 5); my $request = "$type $path HTTP/1.0\n". "Host: $host\n". "Cookie: $cookies\n"; if($type eq "POST") { $request .= "Content-type: application/x-www-form-urlencoded\n". "Content-Length: ".length($data)."\n\n".$data; } else { $request .= "\n"; } print $sock $request; my $answ = undef; while(my $buf = <$sock>) { $answ .= $buf; } return $answ; }
спасибо за ответы. Теперь всё работает, по видимому всё дело было в recv p.s: а до Kaimi мне еще жить и жить)))