#!/usr/bin/perl -W # TP proxy HTTP # # Question 4 # # réponse basée sur celle de la question 2 (pas de prise en compte du keep-alive) # # Antoine Miné # 15/05/2007 use IO::Socket::INET; # on utilise l'interface orientée-objet # filtre d'URLs open AD,".ads"; $filter = ; chop $filter; close AD; # création de la socket d'écoute $listen = new IO::Socket::INET(LocalPort => '8080', Proto => 'tcp', Listen => 5, ReuseAddr => 1, ) or die "échec de création de la socket d'écoute: $!"; # boucle de traitement des connections while ($client = $listen->accept()) { # lit la requête $req = <$client>; ($url) = $req =~ m!GET (\S*) HTTP/1.?! or die "requête non reconnue: $_"; print "requête entrante: $url\n"; # lit et filtre les en-têtes @headers = (); # accumulateur d'en-têtes $host = undef; while ($l = <$client>) { last if $l =~ /^\r\n$/; # récupère le contenu de l'en-tête host $host = $1 if $l =~ /^host:\s*(\S+)/i; # ignore les en-têtes (Proxy-)Connection next if $l =~ /^proxy-connection:/i; next if $l =~ /^connection:/i; push @headers, $l; } # envoie la requête au vrai serveur unless (defined($host) && ($serv = new IO::Socket::INET(PeerAddr => $host, PeerPort => '80', Proto => 'tcp', ))) { # si on échoue à contacter le serveur print $client "HTTP/1.1 502 Bad Gateway\r\n"; print $client "Connection: close\r\n"; print $client "Content-type: text/html\r\n"; print $client "\r\n"; print $client "Erreur!\r\n"; print $client "

Je n'ai pas trouvé $host.\r\n"; next; } print $serv "$req"; print $serv "Connection: close\r\n"; foreach $k (@headers) { print $serv "$k"; } print $serv "\r\n"; # lit la réponse (statu + en-têtes) du serveur $statu = <$serv>; @headers = (); $img = 0; while ($l = <$serv>) { last if $l =~ /^\r\n$/; $img = 1 if $l =~ /image/i; # détecte les images par les en-têtes push @headers, $l; } # détecte les images par l'extension $img = 1 if ($url =~ /\.gif$/i || $l =~ /\.png$/i || $l =~ /\.jp(e?)g$/i); if ($img==1 && $url =~ /$filter/o) { # envoie une image transparent au client print "filtrée\n"; print $client "HTTP/1.1 200 OK\r\n"; print $client "Connection: close\r\n"; print $client "Content-type: image/png\r\n"; print $client "Content-length: 70\r\n"; print $client "\r\n"; print $client "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"; print $client "\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4"; print $client "\x89\x00\x00\x00\x0D\x49\x44\x41\x54\x08\xD7\x63\x60\x60\x60\x60"; print $client "\x00\x00\x00\x05\x00\x01\x5E\xF3\x2A\x3A\x00\x00\x00\x00\x49\x45"; print $client "\x4E\x44\xAE\x42\x60\x82"; } else { # envoie la réponse au client print $client "$statu"; foreach $k (@headers) { print $client "$k"; } print $client "\r\n"; # renvoie le corps de la réponse while ($l = <$serv>) { print $client $l; } } close $client; close $serv; }