Sockets... HTTP... Proxi... ARGHHH!
Philipp Hasenfratz
- perl
Halihallo Forumer
Mein Thread ist leider bereits ins Archiv gerutscht und ist dort noch nicht auffindbar (aus bekannten Gründen), also erstmal Entschuldigung, dass ich nach so kurzer Zeit schon wieder damit anfange, aber das Problem geht mir gewaltig auf die Nerven und ich will schnellstmöglich eine Lösung finden, sonst werd ich noch wahnsinnig ;-)
Es geht um einen HTTP oder Proxi-Dienst. Ein Prog hängt sich an einen Port (80, 8080) und soll die Requests bearbeiten. Funktioniert alles toll. Nur...
while ( my $client = $sock->accept ) {
xxx
}
bei xxx hab ich so ziemlich alles ausprobiert, was ich kenne, um den ganzen HTTP-Request einzulesen... @arr = <$client>; $t = <$client>, while ( <$client> ), ... alles, alles, sogar mit $client->eof... Ich denke, dass es noch eine möglichkeit über recv oder sysread gäbe, aber das muss doch schon einfacher gehen (d. h. beides ist gleich einfach, aber ersteres "perliger"), oder?
Irgendwie erkennt mein Perl nie, wann schluss ist. Das Programm bleibt immer stehen und versuche aus dem Socket zu lesen, obwohl der Client gar nix mehr gesendet hat... Könnte es sein, dass dies mit dem Linedeliminator zu tun hat? (benutze Win => CRLF)...
Was zum h*** ist hier los??? - Was begreife ich hier nicht? - Und warum funktioniert es nur bei HTTP so; andere Socketdiskussionen hab ich ohne Probleme machen können (gar bidirektional mit mehreren Blöcken)? - Aber diese HTTP-Requests (Header _und_ Body) kann ich einfach nicht einlesen... Natürlich könnte ich last if ($line=~/^$crlf$/); machen, aber dann schneide ich mir den Content (eg. POST Formulardaten) des Requests weg und den will ich auch.
Viele Grüsse
Philpp
--> der auf das Ende seiner Qualen hofft ;-)
Hallo,
Natürlich könnte ich last if ($line=~/^$crlf$/); machen, aber dann schneide ich mir den Content (eg. POST Formulardaten) des Requests weg und den will ich auch.
die entspr. RFC's sehen auch nichts anderes vor. Dein Request endet mit dem Header-End. Wenn es noch Daten gibt, dann gibt es auch ein Content-Length. Du mußt bei HTTP den Header parsen, ob Du willst oder nicht. Wenn ich mich nicht irre, so schickst Du bei HTTP/1.0 den Header an den Server und dieser antwortet dann mit dem Status 100, wenn er den Rest haben will.
micha
Halihallo micha
Natürlich könnte ich last if ($line=~/^$crlf$/); machen, aber dann schneide ich mir den Content (eg. POST Formulardaten) des Requests weg und den will ich auch.
die entspr. RFC's sehen auch nichts anderes vor. Dein Request endet mit dem Header-End. Wenn es noch Daten gibt, dann gibt es auch ein Content-Length. Du mußt bei HTTP den Header parsen, ob Du willst oder nicht. Wenn ich mich nicht irre, so schickst Du bei HTTP/1.0 den Header an den Server und dieser antwortet dann mit dem Status 100, wenn er den Rest haben will.
OK. Danke für den Tipp bezüglich Content-Length; ich dachte, dass dies auch anders funktioniert. Aber nun denn...
Was hier Status 100??? - Der Content wird einfach mit \015\012\015\012 an den Header gehängt.
Viele Grüsse
Philipp
Hallo,
Was hier Status 100???
100 Continue, wobei ich jetzt wirklich nicht weiß, ob das nun bei HTTP/1.0 oder 1.1 reinkommt und ob es wichtig ist.
- Der Content wird einfach mit \015\012\015\012 an den Header gehängt.
Der Header wird damit abgeschlossen. Es muß keinen Body geben aber wenn, dann komm er gleich danach. Weiterhin reicht es schon aus auf \012 zu prüfen:
(19.3 Tolerant Applications)
The line terminator for message-header fields is the sequence CRLF.
However, we recommend that applications, when parsing such headers,
recognize a single LF as a line terminator and ignore the leading CR.
<
micha
Hallo Philipp,
while ( my $client = $sock->accept ) {
xxx
}
bei xxx hab ich so ziemlich alles ausprobiert, was ich kenne, um den ganzen
HTTP-Request einzulesen... @arr = <$client>; $t = <$client>,
while ( <$client> ), ... alles, alles, sogar mit $client->eof...
Das funktioniert so nicht :)
Du musst das anders machen. Du musst den Header zeilenweise einlesen und
verarbeiten, z. B. so:
my %headers;
$headers{_firstline} = <$sock>;
while(<$sock>) {
last if m/^\s*$/;
if(m/^(\S+): (.*)$/) {
$headers{$1} = $2;
}
}
my $data;
if($headers{_firstline} =~ /^POST/) {
read $sock, $data, $headers{Content-Length};
}
my $ssock = new IO::Socket::INET(
PeerPort => 80,
PeerAddr => adresse
);
delete $headers{Connection} if exists $headers{Connection};
print delete $headers{_firstline},"\015\012";
print $ssock $_,": ",$headers{$_},"\015\012" foreach keys %headers;
print $ssock "Connection: close\015\012\015\012";
Und dann die Daten vom Server abholen und an den Client schicken. Hier kannst
du recht einfach mit @lines = <$ssock> arbeiten, weil du dem Server ja gesagt
hast, 'du, ich will, dass die Verbindung geschlossen wird!'.
Beim einlesen vom Client funktioniert das deshalb nicht, weil der Socket ja
die ganze Zeit offen bleibt. Der <>-Operator blockt dann, wenn der Client
nichts mehr schickt, weil er auf weitere Daten wartet.
Gruesse,
CK
Halihallo Christian
Das funktioniert so nicht :)
Das musste ich schmerzlich auch feststellen :-)
Du musst das anders machen.
und das die logische Folge ;)
Du musst den Header zeilenweise einlesen und
verarbeiten, z. B. so:
my %headers;
$headers{_firstline} = <$sock>;
while(<$sock>) {
last if m/^\s*$/;
if(m/^(\S+): (.*)$/) {
$headers{$1} = $2;
}
}
soweit war ich schon mal...
my $data;
if($headers{_firstline} =~ /^POST/) {
read $sock, $data, $headers{Content-Length};
}
OK. Also, dann muss ich das so machen, wie ihr (micha hat das ja ebenfalls genannt).
Beim einlesen vom Client funktioniert das deshalb nicht, weil der Socket ja
die ganze Zeit offen bleibt. Der <>-Operator blockt dann, wenn der Client
nichts mehr schickt, weil er auf weitere Daten wartet.
Das verwirrt mich jetzt etwas. Bei anderen Scripts hat das bei mir bestens funktioniert, oder irre ich mich? (also: ist es normalerweise nicht so, dass Perl merkt, wann keine Daten mehr gesendet wurden? - Und ich spreche von Sockets, die nicht geschlossen wurden)...
Also sowas:
Server:
print $client 'hello world'
my @answer = <$sock>;
print $client join("\n", @answer);
Client:
@server = <$sock>;
print $sock 'Re: hello world';
print 'I wrote: '.join('', <$sock>);
ich glaube, dass ich sowas in der Art schon realisieren konnte, also mit offenen Sockets dennoch den <>-Operator verwenden.
Besten dank euch beiden. Hat mir sehr geholfen
Viele Grüsse
Philipp
Hallo Philipp,
my $data;
if($headers{_firstline} =~ /^POST/) {
read $sock, $data, $headers{Content-Length};
}
OK. Also, dann muss ich das so machen, wie ihr (micha hat
das ja ebenfalls genannt).
Micha hat etwas anderes gesagt, aber gut.
Das verwirrt mich jetzt etwas. Bei anderen Scripts hat das
bei mir bestens funktioniert, oder irre ich mich? (also:
ist es normalerweise nicht so, dass Perl merkt, wann keine
Daten mehr gesendet wurden? - Und ich spreche von Sockets,
die nicht geschlossen wurden)...
Nein. Definitiv nicht -- wie soll Perl das auch merken? Die
TCP-Verbindung muss ja nicht zwangslaeufig auf demselben
Rechner sein, sondern kann einmal um die ganze Welt gehen
oder in ein Netzwerk, wo gerade heftigst Probleme sind.
Gruesse,
CK
Halihallo Christian
Das verwirrt mich jetzt etwas. Bei anderen Scripts hat das
bei mir bestens funktioniert, oder irre ich mich? (also:
ist es normalerweise nicht so, dass Perl merkt, wann keine
Daten mehr gesendet wurden? - Und ich spreche von Sockets,
die nicht geschlossen wurden)...
Nein. Definitiv nicht -- wie soll Perl das auch merken? Die
TCP-Verbindung muss ja nicht zwangslaeufig auf demselben
Rechner sein, sondern kann einmal um die ganze Welt gehen
oder in ein Netzwerk, wo gerade heftigst Probleme sind.
Ja. Da hast'e recht. Scheint, als ob ich da ein kleineres Verständnisproblem hatte. Ich hätte mir gut vorstellen können, dass über das Socket eine Art EOF-Command gesendet wird, sodass das API weiss, wann Schluss ist. Aber danke für die "Auffrischung".
Viele Grüsse und Danke an dich/euch
Philipp
Halihallo Forumer
so. Jetzt hatte ich endlich Zeit das ganze auch auszuprobieren und es funktioniert perfekt, naja, fast, sonst müsste ich hier nicht schreiben ;)... Danke nochmals für deine Beispiele, Christian; ich hoffe du erlaubst, dass ich diese gleich verwendet habe (ging einfach schneller, als alles nochmal selber zu programmieren).
Alles, bis auf google.ch funktioniert. GET/POST Daten, Cookies, ... einfach alles, bis auf diesen Google... Wenn ich nämlich diese Seite lade, dann geht der Browser in eine Endlosschlaufe und lädt die Page immer neu. Ich glaube, dass es an dem Status 302 hängt bzw. an Proxy-Connection: Keep-Alive??? - Mal schaun, was ihr dazu meint:
Viele Grüsse
Philipp
PS: Ganz unten noch der momentane Code...
Request on http://www.google.ch/
Request-Header:
Proxy-Connection: Keep-Alive
Host: www.google.ch
Cookie: PREF=ID=2ee932854a6b966a:LD=de:TM=1029179593:LM=1029179593:S=yXSkNolyuIg
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Accept-Language: de
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Request-Content: (Length: )
Request answer from http://www.google.ch/
HTTP/1.0 302 Found
Content-Length: 151
Connection: Close
Server: GWS/2.0
Content-Type: text/html
Date: Sat, 17 Aug 2002 12:39:38 GMT
Location: http://www.google.ch/
Set-Cookie: PREF=ID=1a0d0e7e7e467b7d:TM=1029587978:LM=1029587978:S=oKKDkzioSrA; domain=.google.com; path=/; expires=Sun, 17-Jan-2038 19:14:07 GMT
----
#!/usr/bin/perl
use IO::Socket::INET;
use LWP::Simple;
my $socket = new IO::Socket::INET( LocalAddr => 'localhost',
LocalPort => 8080,
Listen => 5,
Reuse => 1,
Proto => 'tcp' )
or die 'cannot initialise listener';
my %hosts = ( 'http://www.thedorcx.ch/' => 'http://127.0.0.1/www.thedorcx.ch/',
'http://www.kodex.ch/' => 'http://127.0.0.1/www.kodex.ch/',
'http://www.test.ch/' => 'http://127.0.0.1/www.test.ch/' );
open( LOG, '>>./log.txt' );
while ( my $sock = $socket->accept ) {
my %headers; my %_headers;
$headers{_firstline} = <$sock>;
while(<$sock>) {
last if m/^\s*$/;
if(m/^(\S+): (.*)$/) {
my $n = $1; my $v = $2;
$n =~ s/\015|\012//g;
$v =~ s/\015|\012//g;
$headers{$n} = $v;
$_headers{lc $n} = $v;
}
}
my $data='';
if($headers{_firstline} =~ /^POST/) {
read $sock, $data, $_headers{'content-length'};
}
$request = $headers{_firstline};
$request =~ /^(.*?) (.*) HTTP/(.*?)$/i;
my $url = $2;
my $method = $1;
my $vers = $3;
while ( my ($host, $vd_refer) = each %hosts ) {
$url =~ s/$host/$vd_refer/ig;
}
my $server = (split ///, $url)[2];
delete $headers{_firstline};
print LOG 'Request on '.$url."\n";
print 'Request on '.substr($url,0,64)."...\n";
print LOG ' Request-Header:'."\n";
while ( my ($n,$v) = each %headers ) {
print LOG ' ' x 6 . $n . ': ' . $v . "\n";
}
print LOG ' Request-Content: (Length: '.$_headers{'content-length'}.')'."\n";
if (length $data) {
print LOG $data . "\n";
}
my $ssock = new IO::Socket::INET(
PeerAddr => $server,
PeerPort => 80,
Type => SOCK_STREAM,
Timeout => 120
) or next;
delete $headers{Connection} if exists $headers{Connection};
print $ssock "$method $url HTTP/$vers\015\012";
foreach (keys %headers) {
print $ssock $_.": ".$headers{$_}."\015\012";
}
print $ssock "Connection: close\015\012\015\012";
print $ssock $data;
print LOG ' Request answer from '.$url."\n";
my $log = 1;
while ( <$ssock> ) {
if ($_ =~ /^\s*$/) { $log = 0; }
print LOG ' ' x 6 . $_ if $log;
print $sock $_;
}
}
close LOG;
Halihallo Forumer
Ich liebe es, wenn ein Plan funktioniert... Ach, wenn einer mal seine Mitarbeiter/Chefs/I-NetCaffee überpfüfen möchte, wo und was sie im INet surfen, nur den Proxi auf das Script setzen und...
auszug aus'm proxi-log für den Request - fo_posting des letzten Postings... Big Brother is watching you!...
Viele Grüsse
Philipp
Request on http://forum.de.selfhtml.org/cgi-bin/fo_posting.pl
Request-Header:
Pragma: no-cache
Proxy-Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Host: forum.de.selfhtml.org
Content-Length: 6116
Referer: http://forum.de.selfhtml.org/?m=114967&t=20533
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: de
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Request-Content: (Length: 6116)
fup=20533%3B114967&unid=Yx9pHc1FdcUF_LcCyLGeg_&qchar=%FF%BB%BB+&name=Philipp+Hasenfratz&email=philipp.hasenfratz@gmx.net&body=Halihallo+Forumer%0D%0A%0D%0Aso.+Jetzt+hatte+ich+endlich+Zeit+das+ganze+auch+auszuprobieren+und+es+funktioniert+perfekt%2C+naja%2C+fast%2C+sonst+m%FCsste+ich+hier+nicht+schreiben+%3B%29...+Danke+nochmals+f%FCr+deine+Beispiele%2C+Christian%3B+ich+hoffe+du+erlaubst%2C+dass+ich+diese+gleich+verwendet+habe+%28ging+einfach+schneller%2C+als+alles+nochmal+selber+zu+programmieren%29.%0D%0A%0D%0AAlles%2C+bis+auf+google.ch+funktioniert.+GET%2FPOST+Daten%2C+Cookies%2C+...+einfach+alles%2C+bis+auf+diesen+Google...+Wenn+ich+n%E4mlich+diese+Seite+lade%2C+dann+geht+der+Browser+in+eine+Endlosschlaufe+und+l%E4dt+die+Page+immer+neu.+Ich+glaube%2C+dass+es+an+dem+Status+302+h%E4ngt+bzw.+an+Proxy-Connection%3A+Keep-Alive%3F%3F%3F+-+Mal+schaun%2C+was+ihr+dazu+meint%3A%0D%0A%0D%0AViele+Gr%FCsse%0D%0A%0D%0APhilipp%0D%0A%0D%0APS%3A+Ganz+unten+noch+der+momentane+Code...%0D%0A%0D%0ARequest+on+http%3A%2F%2Fwww.google.ch%2F%0D%0A+++Request-Header%3A%0D%0A++++++Proxy-Connection%3A+Keep-Alive%0D%0A++++++Host%3A+www.google.ch%0D%0A++++++Cookie%3A+PREF%3DID%3D2ee932854a6b966a%3ALD%3Dde%3ATM%3D1029179593%3ALM%3D1029179593%3AS%3DyXSkNolyuIg%0D%0A++++++User-Agent%3A+Mozilla%2F4.0+%28compatible%3B+MSIE+6.0%3B+Windows+NT+5.1%29%0D%0A++++++Accept-Language%3A+de%0D%0A++++++Accept%3A+image%2Fgif%2C+image%2Fx-xbitmap%2C+image%2Fjpeg%2C+image%2Fpjpeg%2C+application%2Fvnd.ms-excel%2C+application%2Fvnd.ms-powerpoint%2C+application%2Fmsword%2C+*%2F*%0D%0A+++Request-Content%3A+%28Length%3A+%29%0D%0A+++Request+answer+from+http%3A%2F%2Fwww.google.ch%2F%0D%0A++++++HTTP%2F1.0+302+Found%0D%0A++++++Content-Length%3A+151%0D%0A++++++Connection%3A+Close%0D%0A++++++Server%3A+GWS%2F2.0%0D%0A++++++Content-Type%3A+text%2Fhtml%0D%0A++++++Date%3A+Sat%2C+17+Aug+2002+12%3A39%3A38+GMT%0D%0A++++++Location%3A+http%3A%2F%2Fwww.google.ch%2F%0D%0A++++++Set-Cookie%3A+PREF%3DID%3D1a0d0e7e7e467b7d%3ATM%3D1029587978%3ALM%3D1029587978%3AS%3DoKKDkzioSrA%3B+domain%3D.google.com%3B+path%3D%2F%3B+expires%3DSun%2C+17-Jan-2038+19%3A14%3A07+GMT%0D%0A%0D%0A----%0D%0A%0D%0Aproxi.pl%0D%0A%3D%3D%3D%3D%3D%3D%3D%3D%0D%0A%0D%0A%23%21%2Fusr%2Fbin%2Fperl%0D%0A%0D%0Ause+IO%3A%3ASocket%3A%3AINET%3B%0D%0Ause+LWP%3A%3ASimple%3B%0D%0A%0D%0Amy+%24socket+%3D+new+IO%3A%3ASocket%3A%3AINET%28%09LocalAddr%09%3D%3E+%27localhost%27%2C%0D%0A%09%09%09%09%09LocalPort%09%3D%3E+8080%2C%0D%0A%09%09%09%09%09Listen%09%09%3D%3E+5%2C%0D%0A%09%09%09%09%09Reuse%09%09%3D%3E+1%2C%0D%0A%09%09%09%09%09Proto%09%09%3D%3E+%27tcp%27+%29%0D%0A%09%09or+die+%27cannot+initialise+listener%27%3B%0D%0A%0D%0Amy+%25hosts+%3D+%28%09%27http%3A%2F%2Fwww.thedorcx.ch%2F%27%09%3D%3E+%27http%3A%2F%2F127.0.0.1%2Fwww.thedorcx.ch%2F%27%2C%0D%0A%09%09%27http%3A%2F%2Fwww.kodex.ch%2F%27%09%09%3D%3E+%27http%3A%2F%2F127.0.0.1%2Fwww.kodex.ch%2F%27%2C%0D%0A%09%09%27http%3A%2F%2Fwww.test.ch%2F%27%09%09%3D%3E+%27http%3A%2F%2F127.0.0.1%2Fwww.test.ch%2F%27+%29%3B%0D%0A%0D%0A%23+einige+Domain-Referer%2C+genau+das%2C+wozu+ich+den+Proxi+verwende...%0D%0A%23+also+die+Ursache%2C+warum+ich+erst+angefangen+habe+zu+programmieren.%0D%0A%0D%0Aopen%28+LOG%2C+%27%3E%3E.%2Flog.txt%27+%29%3B%0D%0A%0D%0Awhile+%28+my+%24sock+%3D+%24socket-%3Eaccept+%29+%7B%0D%0A%0D%0A+++my+%25headers%3B+my+%25_headers%3B%0D%0A+++%24headers%7B_firstline%7D+%3D+%3C%24sock%3E%3B%0D%0A%0D%0A+++while%28%3C%24sock%3E%29+%7B%0D%0A+++++last+if+m%2F%5E%5Cs*%24%2F%3B%0D%0A+++++if%28m%2F%5E%28%5CS%2B%29%3A+%28.*%29%24%2F%29+%7B%0D%0A+++++++my+%24n+%3D+%241%3B+my+%24v+%3D+%242%3B%0D%0A+++++++%24n+%3D%7E+s%2F%5C015%7C%5C012%2F%2Fg%3B%0D%0A+++++++%24v+%3D%7E+s%2F%5C015%7C%5C012%2F%2Fg%3B%0D%0A+++++++%24headers%7B%24n%7D+%3D+%24v%3B%0D%0A+++++++%24_headers%7Blc+%24n%7D+%3D+%24v%3B%0D%0A+++++%7D%0D%0A+++%7D%0D%0A%0D%0A+++my+%24data%3D%27%27%3B%0D%0A+++if%28%24headers%7B_firstline%7D+%3D%7E+%2F%5EPOST%2F%29+%7B%0D%0A+++++read+%24sock%2C+%24data%2C+%24_headers%7B%27content-length%27%7D%3B%0D%0A+++%7D%0D%0A%0D%0A+++%24request+%3D+%24headers%7B_firstline%7D%3B%0D%0A+++%24request+%3D%7E+%2F%5E%28.*%3F%29+%28.*%29+HTTP%5C%2F%28.*%3F%29%24%2Fi%3B%0D%0A+++my+%24url++%3D+%242%3B%0D%0A+++my+%24method+%3D+%241%3B%0D%0A+++my+%24vers+%3D+%243%3B%0D%0A%0D%0A+++while+%28+my+%28%24host%2C+%24vd_refer%29+%3D+each+%25hosts+%29+%7B%0D%0A++++++%24url+%3D%7E+s%2F%24host%2F%24vd_refer%2Fig%3B%0D%0A+++%7D%0D%0A+++my+%24server+%3D+%28split+%2F%5C%2F%2F%2C+%24url%29%5B2%5D%3B%0D%0A+++delete+%24headers%7B_firstline%7D%3B%0D%0A%0D%0A+++print+LOG+%27Request+on+%27.%24url.%22%5Cn%22%3B%0D%0A+++print+%27Request+on+%27.substr%28%24url%2C0%2C64%29.%22...%5Cn%22%3B%0D%0A+++print+LOG+%27+++Request-Header%3A%27.%22%5Cn%22%3B%0D%0A+++while+%28+my+%28%24n%2C%24v%29+%3D+each+%25headers+%29+%7B%0D%0A++++++print+LOG+%27+%27+x+6+.+%24n+.+%27%3A+%27+.+%24v+.+%22%5Cn%22%3B%0D%0A+++%7D%0D%0A+++print+LOG+%27+++Request-Content%3A+%28Length%3A+%27.%24_headers%7B%27content-length%27%7D.%27%29%27.%22%5Cn%22%3B%0D%0A+++if+%28length+%24data%29+%7B%0D%0A++++++print+LOG+%24data+.+%22%5Cn%22%3B%0D%0A+++%7D%0D%0A%0D%0A+++my+%24ssock+%3D+new+IO%3A%3ASocket%3A%3AINET%28%0D%0A+++++PeerAddr+%3D%3E+%24server%2C%0D%0A+++++PeerPort+%3D%3E+80%2C%0D%0A+++++Type+++++%3D%3E+SOCK_STREAM%2C%0D%0A+++++Timeout++%3D%3E+120%0D%0A+++%29+or+next%3B%0D%0A%0D%0A+++delete+%24headers%7BConnection%7D+if+exists+%24headers%7BConnection%7D%3B%0D%0A%0D%0A+++print+%24ssock+%22%24method+%24url+HTTP%2F%24vers%5C015%5C012%22%3B%0D%0A%0D%0A+++foreach+%28keys+%25headers%29+%7B%0D%0A++++++print+%24ssock+%24_.%22%3A+%22.%24headers%7B%24_%7D.%22%5C015%5C012%22%3B%0D%0A+++%7D%0D%0A%0D%0A+++print+%24ssock+%22Connection%3A+close%5C015%5C012%5C015%5C012%22%3B%0D%0A+++print+%24ssock+%24data%3B%0D%0A%0D%0A+++print+LOG+%27+++Request+answer+from+%27.%24url.%22%5Cn%22%3B%0D%0A+++my+%24log+%3D+1%3B%0D%0A+++while+%28+%3C%24ssock%3E+%29+%7B%0D%0A++++++if+%28%24_+%3D%7E+%2F%5E%5Cs*%24%2F%29+%7B+%24log+%3D+0%3B+%7D%0D%0A++++++print+LOG+%27+%27+x+6+.+%24_+if+%24log%3B%0D%0A++++++print+%24sock+%24_%3B%0D%0A+++%7D%0D%0A%7D%0D%0A%0D%0Aclose+LOG%3B&url=http%3A%2F%2F&image=http%3A%2F%2F
Request answer from http://forum.de.selfhtml.org/cgi-bin/fo_posting.pl
HTTP/1.1 200 OK
Date: Sat, 17 Aug 2002 12:45:13 GMT
Server: Apache/1.3.26 (Unix) PHP/4.2.1 mod_gzip/1.3.19.1a
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Hallo,
also in Perl kenne ich mich nicht aus, hätte aber wahrscheinlich den einen oder anderen reg. Ausdruck anders geschrieben. Beispielsweise
$n =~ s/\015|\012//g;
$v =~ s/\015|\012//g;
Da wäre ein
$n =~ s/\015?\012//g;
$v =~ s/\015?\012//g;
näher an den Specs, weil es da heißt, dass nicht auf CR geprüft werden muss (tolerante Apps). Bei deinem reg. Ausdruck wäre es egal was da am Ende steht. Ein kleiner aber feiner Unterschied.
Aber eigentlich wollte ich nur fragen wo dein $header geleert wird, damit nicht alte Werte drinstehen?
Ich glaube, dass es an dem Status 302 hängt bzw. an Proxy-Connection: Keep-Alive??? - Mal schaun, was ihr dazu meint:
302 steht doch normalerweise für "Moved Temporarily". Warum steht in deinem Log "302 Found"? Was das Keep-Alive betrifft, ist es so, sofern ich die Specs richtig verstanden habe, dass bei HTTP/1.0 explizit erklärt werden muss, dass eine Verbindung persistent ist (keep-alive, aufrecht erhalten) und bei HTTP/1.1 ist es genau umgekehrt. Es wird stets davon ausgegangen, dass eine Verbindung persistent ist, und durch ein "Connection: close" wird mitgeteilt, dass sie geschlossen wird.
Könntest du die entspr. Headers (Request, Response) komplett posten? Denn da wäre es für mich als Perl-Unwissender einfacher einen Fehler zu erkennen.
micha
Halihallo
also in Perl kenne ich mich nicht aus, hätte aber wahrscheinlich den einen oder anderen reg. Ausdruck anders geschrieben. Beispielsweise
$n =~ s/\015|\012//g;
$v =~ s/\015|\012//g;
Da wäre ein
$n =~ s/\015?\012//g;
$v =~ s/\015?\012//g;
ich glaube, dass beide RegExp genau das selbe machen ;)
wegen dem g, da werden bei mir _alle_ \015 und _alle_ \012 gelöscht, bei dir macht es genau das selbe
näher an den Specs, weil es da heißt, dass nicht auf CR geprüft werden muss (tolerante Apps). Bei deinem reg. Ausdruck wäre es egal was da am Ende steht. Ein kleiner aber feiner Unterschied.
ich sehe keinen Unterschied...
Aber eigentlich wollte ich nur fragen wo dein $header geleert wird, damit nicht alte Werte drinstehen?
Ich habe in etwa das übernommen, was Christian gepostet hat. Dort wird eigentlich nur das Connection: Feld gelöscht und durch Connection: close ersetzt. Dann wird die ganze Page eingelesen und an den Client ungeändert zurückgesendet...
Ich glaube, dass es an dem Status 302 hängt bzw. an Proxy-Connection: Keep-Alive??? - Mal schaun, was ihr dazu meint:
302 steht doch normalerweise für "Moved Temporarily". Warum steht in deinem Log "302 Found"?
Ja, s. unten.
Was das Keep-Alive betrifft, ist es so, sofern ich die Specs richtig verstanden habe, dass bei HTTP/1.0 explizit erklärt werden muss, dass eine Verbindung persistent ist (keep-alive, aufrecht erhalten) und bei HTTP/1.1 ist es genau umgekehrt. Es wird stets davon ausgegangen, dass eine Verbindung persistent ist, und durch ein "Connection: close" wird mitgeteilt, dass sie geschlossen wird.
Ist mir klar. Ich kann mir nur nicht erklären, warum der Browser in eine Endlosschleife kommt, wenn ich www.google.ch aufrufe. 302 => Temporarely Moved => denkt da der Browser, dass er es einfach solange versuchen soll, bis er eine gültige 200-er als Antwort bekommt?
Könntest du die entspr. Headers (Request, Response) komplett posten? Denn da wäre es für mich als Perl-Unwissender einfacher einen Fehler zu erkennen.
Her der Auszug. Ich poste hier zwei Requests. Wenn ich google.ch aufrufe, geht er wie gesagt in einen Endlosrequest über und versucht immer wieder von neuem google.ch zu öffnen. "Request-Header" und "Request-Content" sind die Daten, die der Browser an den Proxi sendet. "Request answer" ist dann die Antwort von google.ch (den Content lass ich lieber nicht loggen, sonst ist meine HD ziemlich schnell voll ;))
Viele Grüsse und Danke
Philipp
--- LOG ---
Request on http://www.google.ch/
Request-Header:
Proxy-Connection: Keep-Alive
Host: www.google.ch
Cookie: PREF=ID=2ee932854a6b966a:LD=de:TM=1029179593:LM=1029179593:S=yXSkNolyuIg
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Accept-Language: de
Request-Content: (Length: )
Request answer from http://www.google.ch/
HTTP/1.0 302 Found
Content-Length: 151
Connection: Close
Server: GWS/2.0
Content-Type: text/html
Date: Mon, 19 Aug 2002 09:07:49 GMT
Location: http://www.google.ch/
Set-Cookie: PREF=ID=1f1fd7ba1fe8791b:TM=1029748069:LM=1029748069:S=IT0SXd9GVIY; domain=.google.com; path=/; expires=Sun, 17-Jan-2038 19:14:07 GMT
Request on http://www.google.ch/
Request-Header:
Proxy-Connection: Keep-Alive
Host: www.google.ch
Cookie: PREF=ID=2ee932854a6b966a:LD=de:TM=1029179593:LM=1029179593:S=yXSkNolyuIg
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Accept-Language: de
Request-Content: (Length: )
Request answer from http://www.google.ch/
HTTP/1.0 302 Found
Content-Length: 151
Connection: Close
Server: GWS/2.0
Content-Type: text/html
Date: Mon, 19 Aug 2002 09:07:50 GMT
Location: http://www.google.ch/
Set-Cookie: PREF=ID=44111b0c6b28a7b8:TM=1029748070:LM=1029748070:S=ZUCAc68Nae4; domain=.google.com; path=/; expires=Sun, 17-Jan-2038 19:14:07 GMT