원격 서버에서 많은 수의 파일을 다운로드하는 Perl 스크립트가 있습니다. 나는 서버를 망치는 것을 피하고 싶다. 그래서 마지막 검사 이후 수정되지 않았다면 파일 다운로드를 피하고 싶다. Perl이나 쉘 스크립트에서이 작업을 수행 할 수있는 좋은 방법이 있습니까?perl (또는 wget)이 포함 된 신규/수정 된 파일 만 다운로드
수정되지 않은 파일에 대해 서버가 HTTP 200 대신 HTTP 304을 보낼 수 있습니까?
원격 서버에서 많은 수의 파일을 다운로드하는 Perl 스크립트가 있습니다. 나는 서버를 망치는 것을 피하고 싶다. 그래서 마지막 검사 이후 수정되지 않았다면 파일 다운로드를 피하고 싶다. Perl이나 쉘 스크립트에서이 작업을 수행 할 수있는 좋은 방법이 있습니까?perl (또는 wget)이 포함 된 신규/수정 된 파일 만 다운로드
수정되지 않은 파일에 대해 서버가 HTTP 200 대신 HTTP 304을 보낼 수 있습니까?
예, LWP::UserAgent
을 사용하고 mirror
방법에 특히주의하십시오. 절차 LWP::Simple
에서 mirror
기능으로 사용할 수도 있습니다. LWP
의 POD에서
:
이 방법은 $ URL에 의해 식별되는 문서를 얻을라는 파일 $ 파일 이름에 저장됩니다. 파일이 이미 존재하면 파일의 수정 시간과 일치하는 "If-Modified-Since"헤더가 요청에 포함됩니다. 이 시간 이후로 서버의 문서가 변경되지 않은 경우 아무 일도 발생하지 않습니다. 문서가 업데이트되면 다시 다운로드됩니다. 파일의 수정 시간은 서버의 수정 시간과 일치해야합니다.
반환 값은 응답 개체입니다.
HTTP 304는 If-Modified-Since 테스트를 통과하고 복사본이 최신 인 경우 서버가 반환 할 응답 코드입니다. LWP는 내부적으로 mirror
을 사용합니다. 걱정할 필요가 없습니다.
감사합니다. 파일을 실제로 가지지 않고 If-Modified-Since를 보내는 방법이 있습니까? 파일을 다운로드하고 파일이 올바른지 확인하고 그렇지 않은 경우 진단을받습니다. 그렇지 않으면 파일을 삭제하고 계속합니다. – Charles
예. 저기있다. 그러나 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'를 서브 클래 싱하면 실제로 정말 멋진 작업을 수행 할 수 있습니다. –
나는 무언가가 존재했음을 기쁘게 생각합니다. 이것이 소켓 인터페이스를 코딩 할 준비가되었지만, 약간의 HTTP와 Perl 코드를 작성하는 것보다 더 많은 것을 할 필요는없는 것처럼 보입니다. 모든 조언을 제공해 주셔서 감사합니다. 전에 LWP에 대해 들어 보지 못했습니다 ... 나는 CPAN에 더 많은 시간을 할애해야한다고 생각합니다. – Charles
이것은 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";
}
'rsync'는 HTTP 프로토콜 대신 구현할 수있는 해결책이 아닙니까? – Wrikken
@Wrikken : 아니오, 내 서버가 아닙니다! – Charles