2010-08-04 3 views
3

원격 서버에서 많은 수의 파일을 다운로드하는 Perl 스크립트가 있습니다. 나는 서버를 망치는 것을 피하고 싶다. 그래서 마지막 검사 이후 수정되지 않았다면 파일 다운로드를 피하고 싶다. Perl이나 쉘 스크립트에서이 작업을 수행 할 수있는 좋은 방법이 있습니까?perl (또는 wget)이 포함 된 신규/수정 된 파일 만 다운로드

수정되지 않은 파일에 대해 서버가 HTTP 200 대신 HTTP 304을 보낼 수 있습니까?

+0

'rsync'는 HTTP 프로토콜 대신 구현할 수있는 해결책이 아닙니까? – Wrikken

+0

@Wrikken : 아니오, 내 서버가 아닙니다! – Charles

답변

5

예, LWP::UserAgent을 사용하고 mirror 방법에 특히주의하십시오. 절차 LWP::Simple에서 mirror 기능으로 사용할 수도 있습니다. LWP의 POD에서

:

이 방법은 $ URL에 의해 식별되는 문서를 얻을라는 파일 $ 파일 이름에 저장됩니다. 파일이 이미 존재하면 파일의 수정 시간과 일치하는 "If-Modified-Since"헤더가 요청에 포함됩니다. 이 시간 이후로 서버의 문서가 변경되지 않은 경우 아무 일도 발생하지 않습니다. 문서가 업데이트되면 다시 다운로드됩니다. 파일의 수정 시간은 서버의 수정 시간과 일치해야합니다.

반환 값은 응답 개체입니다.

HTTP 304는 If-Modified-Since 테스트를 통과하고 복사본이 최신 인 경우 서버가 반환 할 응답 코드입니다. LWP는 내부적으로 mirror을 사용합니다. 걱정할 필요가 없습니다.

+0

감사합니다. 파일을 실제로 가지지 않고 If-Modified-Since를 보내는 방법이 있습니까? 파일을 다운로드하고 파일이 올바른지 확인하고 그렇지 않은 경우 진단을받습니다. 그렇지 않으면 파일을 삭제하고 계속합니다. – Charles

+2

예. 저기있다. 그러나 LWP에서는 [HTTP :: Request] (http://search.cpan.org/~gaas/libwww-perl-5.836/lib/HTTP/Request.pm) 및 '$ ua- > request()'를 직접 호출하십시오. [LWP :: UserAgent] (http://cpansearch.perl.org/src/GAAS/libwww-perl-5.836/lib/LWP/UserAgent.pm)의 출처를 확인하여 미러 하위 정의를 읽습니다. 'LWP ​​:: UserAgent'를 서브 클래스 화하여 미러를 오버라이드 할 수 있습니다.이 작업을 투명하게 수행하려면'LWP :: UserAgent'를 서브 클래 싱하면 실제로 정말 멋진 작업을 수행 할 수 있습니다. –

+1

나는 무언가가 존재했음을 기쁘게 생각합니다. 이것이 소켓 인터페이스를 코딩 할 준비가되었지만, 약간의 HTTP와 Perl 코드를 작성하는 것보다 더 많은 것을 할 필요는없는 것처럼 보입니다. 모든 조언을 제공해 주셔서 감사합니다. 전에 LWP에 대해 들어 보지 못했습니다 ... 나는 CPAN에 더 많은 시간을 할애해야한다고 생각합니다. – Charles

1

이것은 Evan Carrol의 답변에 기반하고 있지만, 다른 사람에게 유용 할 경우에 대해 자세히 설명 할 것입니다. 응답 섹션을 작성했습니다. 내 코드의 일부가 재미 있을지 의심 스럽다.

#!/usr/bin/perl -w 

require HTTP::Date; 
require LWP::UserAgent; 
require Date::Parse; 

my $lastChecked = '2009-01-01'; 
my $ua = LWP::UserAgent->new; 
$ua->default_header('If-Modified-Since' => HTTP::Date::time2str(Date::Parse::str2time($lastChecked))); 

my $response = $ua->get('http://example.com/'); 

if ($response->code == 304) { 
    print "No changes.\n"; 
} elsif ($response->is_success) { 
    print $response->decoded_content; 
} else { 
    print "Response was error " . $response->code . ": '" . $response->status_line . "'\n"; 
} 
관련 문제