inhalte eines https-urls automatisiert runterladen (perl)
seth_not@home
- programmiertechnik
gudn tach!
gegeben: ein url a la "https://$domain".
gesucht: moeglichkeit, sich automatisiert den inhalt, der sich hinter dem url verbirgt, zu holen.
bisher bin ich so vorgegangen, dass ich per firefox auf die webseite gegangen bin und mir die http headers angeschaut habe. anschliessend habe ich versucht, das gleiche in abgespeckter version via perl (module www-mechanize) durchzufuehren. klappt aber nicht und ich weiss nicht, wie ich nun (systematisch) weiter vorgehen sollte.
wenn ich mittels firefox auf oben genannten url gehe, dann liefert mir das firefox-plugin Live HTTP headers:
(um nicht die tatsaechlichen urls preiszugeben, verwende ich platzhalter: $extdomain, $domain, "[...]" fuer ausgelassenes)
========%< Live HTTP headers ========
http://$extdomain/OCSP-Server/OCSP
POST /OCSP-Server/OCSP HTTP/1.1
Host: $extdomain
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.8,de-de;q=0.5,de;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Content-Length: 106
Content-Type: application/ocsp-request
[...]
HTTP/1.1 200 OK
Date: Tue, 16 Jul 2013 10:41:23 GMT
Server: Apache
Content-Length: 3834
Content-Type: application/ocsp-response
Connection: Keep-Alive
Age: 0
----------------------------------------------------------
https://$domain/
GET / HTTP/1.1
Host: $domain
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.8,de-de;q=0.5,de;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cookie: [...]
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="$domain"
X-Powered-By: ASP.NET
Date: Tue, 16 Jul 2013 10:41:22 GMT
Content-Length: 1344
----------------------------------------------------------
https://$domain/
GET / HTTP/1.1
Host: $domain
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.8,de-de;q=0.5,de;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cookie: [...]
Authorization: NTLM [...]
HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/7.5
WWW-Authenticate: NTLM [...]
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="$domain"
X-Powered-By: ASP.NET
Date: Tue, 16 Jul 2013 10:41:48 GMT
Content-Length: 1344
----------------------------------------------------------
https://$domain/
GET / HTTP/1.1
Host: $domain
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.8,de-de;q=0.5,de;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cookie: [...]
Authorization: NTLM [...]
HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: [...]; expires=Wed, 17-Jul-2013 10:41:48 GMT; path=/
Set-Cookie: [...]; expires=Wed, 17-Jul-2013 10:41:48 GMT; path=/
Set-Cookie: [...]; expires=Mon, 11-Oct-1999 22:00:00 GMT; path=/; HttpOnly
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Tue, 16 Jul 2013 10:41:48 GMT
Content-Length: 18406
======== Live HTTP headers >%========
irritierend finde ich dabei diese OCSP-geschichte am anfang. beim aufruf von $domain wird also zunaechst $extdomain aufgerufen, um einen zertifikats-check durchzufuehren.
ich versuchte mein glueck mit folgendem perl-code:
#!/usr/bin/perl
use strict;
use warnings;
use WWW::Mechanize;
use LWP::Authen::Ntlm;
my $user = $ARGV[0];
my $password = $ARGV[1];
my $domain = $ARGV[2];
my $url = "https://$domain";
my $mech = WWW::Mechanize->new('keep_alive' => 1, 'autocheck' => 0);
$mech->agent_alias('Linux Mozilla');
$mech->add_handler("request_send", sub { shift->dump; return });
$mech->add_handler("response_done", sub { shift->dump; return });
$mech->credentials($domain.':80', '', $domain.'\\'.$user, $password);
$mech->get($url);
print ' status: '.$mech->status(), ',';
print ' ct = '.$mech->content_type().',';
ich wollte also ohne diesen expliziten zertifikats-check direkt auf die zieldomain. passieren tut damit allerdings folgendes:
========%< perl-script output ========
GET https://$domain
Accept-Encoding: gzip
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624
(no content)
[dann folgt eine pause von etwa 2 minuten, anschliessend folgt die ausgabe]
HTTP/1.1 401 Unauthorized
Cache-Control: private
Date: Tue, 16 Jul 2013 11:10:39 GMT
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="$domain"
Content-Length: 1344
Content-Type: text/html
Client-Date: Tue, 16 Jul 2013 11:12:53 GMT
Client-Peer: 172.21.172.15:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=DE/O=[...]/CN=[...]/emailAddress=[...]
Client-SSL-Cert-Subject: /C=DE/ST=[...]/L=[...]/O=[...]/CN=$domain
Client-SSL-Cipher: AES128-SHA
Client-SSL-Socket-Class: IO::Socket::SSL
Title: 401 - Nicht autorisiert: Zugriff aufgrund ung�ltiger Anmeldeinformationen verweigert.
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 4.0
X-Powered-By: ASP.NET
======== perl-script output >%========
wie bereits eingangs gesagt, ist meine frage: wie gehe ich nun (systematisch) weiter vor, um mein ziel doch noch zu erreichen?
prost
seth
Tach,
$mech->credentials($domain.':80', '', $domain.'\'.$user, $password);
ist das Realm tatsächlich leer? Nutze doch einfach die [in der Doku](http://search.cpan.org/~jesse/WWW-Mechanize-1.72/lib/WWW/Mechanize.pm#$mech-%3Ecredentials%28_$username,_$password_%29) angegebene Form mit zwei Parametern, um es dir einfacher zu machen; und ist der Username in der angegebenen, zusammengesetzten Form korrekt?
mfg
Woodfighter
Tach,
ist das Realm tatsächlich leer?
nein, ist es nicht, steht ja im OP: „WWW-Authenticate: Basic realm="$domain"“.
mfg
Woodfighter
gudn tach!
$mech->credentials($domain.':80', '', $domain.'\\'.$user, $password);
ist das Realm tatsächlich leer?
hat mich anfangs auch gewundert, aber frueher hatte das mal auf derselben website exakt so funktioniert, obwohl da auch schon dasselbe realm angegeben war. aber vielleicht kommt das nur bei "Basic" zum tragen und nicht bei NTLM bzw. Negotiate?
jedenfalls, so wie hier von mir benutzt, hatte ich es auch in diversen anderen manuals/foren gefunden. deswegen dachte ich, dass das so richtig sei. und wie gesagt, frueher funzte es so.
die website, auf der ich mich einloggen will, ist vor kurzem neugebaut worden. seitdem konnte ich mich nicht mehr per www-mechanize einloggen. (mit dem firefox dagegen gehts.)
Nutze doch einfach die in der Doku angegebene Form mit zwei Parametern, um es dir einfacher zu machen; und ist der Username in der angegebenen, zusammengesetzten Form korrekt?
das problem bleibt bestehen, auch wenn ich
$mech->credentials($domain.':80', $domain, $user, $password);
$mech->credentials($domain.'\\'.$user, $password);
oder
$mech->credentials($user, $password);
benutze.
prost
seth
Authorization-Header fehlt, sieht man doch auf einen Blick!
my $url = "https://$domain";
⋮
$mech->credentials($domain.':80'
~~~merkst du was?
gudn tach!
Authorization-Header fehlt, sieht man doch auf einen Blick!
ja, schon, ok, und weiter?
my $url = "https://$domain";
⋮
$mech->credentials($domain.':80'
oops, der port! danke fuer den hinweis.
daran lag's aber nicht, mit 443 statt 80 hat sich nichts veraendert.
prost
seth
gudn tach!
use LWP::Authen::Ntlm;
da lag offenbar ein problem.
LWP::Authen::Ntlm ist bei mir installiert und mit NTLM wurde die authentifizierung auch versucht. das schlug aber fehl. der grund dafuer ist mir nach wie vor unklar.
aaaber nachdem ich soeben LWP::Authen::Negotiate installiert hatte, wurde die authentifizierung automatisch via Negotiate versucht, und damit klappts. :-)
das einzige problem, dass ich jetzt noch habe, ist dieses ominoese time-delay von ca. 2 min. innerhalb eines requests. dafuer sollte ich vielleicht besser einen neuen thread aufmachen, oder?
prost
seth
Tach,
das einzige problem, dass ich jetzt noch habe, ist dieses ominoese time-delay von ca. 2 min. innerhalb eines requests. dafuer sollte ich vielleicht besser einen neuen thread aufmachen, oder?
neuer Thread ist wohl überflüssig, aber ich würde mir mal die einzelnen Requests (werden vermutlich auch mindestens zwei sein) ansehen, z.B. per Wireshark oder den (vorhandenen?) Debugmöglichkeiten.
mfg
Woodfighter
gudn tach!
das einzige problem, dass ich jetzt noch habe, ist dieses ominoese time-delay von ca. 2 min. innerhalb eines requests.
[...] ich würde mir mal die einzelnen Requests (werden vermutlich auch mindestens zwei sein) ansehen, z.B. per Wireshark oder den (vorhandenen?) Debugmöglichkeiten.
ich denke, ich habe ziemlich genau das gleiche problem wie dieser user bei stackoverflow. auch bei mir ist dieses delay etwa 120 sekunden lang und tritt an derselben stelle auf.
allerdings habe ich die dortige loesung nicht verstanden.
ich habe auf verdacht hin
$mech->add_handler( response_data => sub {
my $res = shift;
if($res->header('Content-Length') == length($res->content)) {
die "OK";
}
return 1;
}
);
bei mir ergaenzt, was am delay nichts geaendert hat. aber um ehrlich zu sein, verstehe ich eh nicht, was dieser handler bringen soll.
ich bin hier auf einem suse-linux-system, aber ohne root-rechte. da bringt mir wireshark wohl nix.
prost
seth
gudn tach!
das einzige problem, dass ich jetzt noch habe, ist dieses ominoese time-delay von ca. 2 min. innerhalb eines requests.
koennte es sein, dass da von www-mechanize ein zeilenumbruch zuwenig gesendet wird und deswegen der server mit seiner antwort wartet? hmm, muss ich morgen noch mal genauer anschauen.
prost
seth
gudn tach!
ach du liebe zeit, irgendwo in den untiefen der module wurde Net::HTTP verwendet. und das hat in der version 6.05 offenbar einen bug. denn nach dem upgrade auf 6.06 funzt der get-request problemlos. trotzdem danke fuer die hilfe!
prost
seth