fsockopen et redirection et offline

Eléphanteau du PHP | 43 Messages

22 déc. 2005, 16:29

Bonjour,

Tout d'abord voici mon script qui recupere la version d'un script sur un serveur distant pour la comparer avec celle installé :
    	echo "<center><b>"._NCVERSIONCHECK."</b></center><br>";
	$socket = fsockopen("www.nukeclan.org", "80");
  	stream_set_timeout($socket, 10);
	$sockettime = stream_get_meta_data($socket);
	if (!$socket OR $sockettime['timed_out']) {
		$errorsock = "1";
	} else {
		$fsock = fopen("http://www.nukeclan.org/NCversion.txt", "r");
		$NCverout = "";
		while (!feof($fsock)) {
  			$NCverout .= fread($fsock, 2048);
		}
	}
	$NCverin = $ncversion;
	if ($errorsock == "1" OR $NCverout == "") {
		echo "<center><font color=\"red\"><b>"._NCERRORSOCK."</b></font><br><br>"._NCVERINSTALLED." : $NCverin";
	} else {
		if (str_replace(".","",$NCverout) > str_replace(".","",$NCverin)) {
			$version_text = "<font color=\"red\"><b>"._VERSIONOLDER."</b></font>";
			$NCverout = "<font color=\"red\"><b>$NCverout</b></font>";
		} else {
			$version_text = "<b>"._VERSIONOK."</b>";
			$NCverin = "<b>$NCverin</b>";
		}
		echo "<center>"._NCVERINSTALLED." : $NCverin - "._NCVERONLINE." : $NCverout<br><br>$version_text</center>";
	}
	@fclose($fsock);
Premiere chose c'est qu'avec l'adresse de redirection ca ne marche pas (message _NCERRORSOCK) tandis qu'avec l'ip du serveur ca marche. Donc par soucis de sécurité j'aimerais que ca marche avec l'adresse de redirection.

Deuxieme chose c'est que lorsqu'on est en local (je fais mes tests en local) et sans connection internet, la page s'interrompt brutalement apres environ 30 secondes de chargement et sans message d'erreur.

Merci de m'indiquer ce qui ne va pas...

Cordialement,
Cadav0r

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

24 déc. 2005, 02:59

Bonsoir,

Pour ton 1er problème donne nous un message d'erreur complet afin qu'on puisse t'aider.

Pour ton deuxième problème, cela provient probablement de la limite d'exécution de 30 secondes de PHP (limite par défaut).
Quoi qu'il en soit si ton script s'exécute en + de 30 secondes c'est qu'il doit y avoir un problème qu'il faut gérer en amont...
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 43 Messages

24 déc. 2005, 13:03

Pour le premier je n'ai pas de message d'erreur PHP j'ai juste mon message a moi (_NCERRORSOCK)

Pour le second c'est normal qu'il n'arrive pas a recuperé les données puisque je ne suis pas connecté a internet a ce moment la mais j'aimerais que si par exemple le serveur est indisponible que le script ne s'arrete pas brutalement car du coup il ne finit pas de charger ma page!!!

ViPHP
ViPHP | 1380 Messages

24 déc. 2005, 16:43

Plusieurs remarques:
  • Le timeout sur le stream fopen ne marche pas (en tout cas pas sans artifice exotique), donc si le fichier txt ne s'ouvre pas convenablement, ton script tournera dans le vide. Le timeout de ton script ne marchera que sur l'ouverture du socket sur le domaine www.nukeclan.org, pas sur le fichier.
    Solution possible--> http://www.phpfrance.com/forums/voir_su ... texte-.php
  • l'url de ton fichier txt pointe sur un frameset. Vas donc voir la source et tu verras que la véritable adresse est http://xxx.xxx.xx.xxx/~nukeclan/NCversion.txt
  • tu pourrais également utiliser simplement file_get_contents mais cette fonction non plus, ne dispose pas de timeout (voir le premier lien)

Edit: masquage de l'IP
Modifié en dernier par Ripat le 25 déc. 2005, 11:11, modifié 1 fois.
ripat

Eléphanteau du PHP | 43 Messages

24 déc. 2005, 18:52

Premier point le stream_timeout est sur le fsockopen pas sur le fopen...

Deuxiemement ce n'est pas un frameset mais une redirection... Et comme je le disais je souhaite utilise l'adresse de redirection dans mon script plutot que l'ip réelle du serveur...

Le but du timeout c'est justement pour eviter que le script tourne alors que le serveur n'est pas en ligne (ou le client...)

ViPHP
ViPHP | 1380 Messages

25 déc. 2005, 10:57

Premier point le stream_timeout est sur le fsockopen pas sur le fopen
...
Le but du timeout c'est justement pour eviter que le script tourne alors que le serveur n'est pas en ligne
Exact. Mais ce ne serait pas une mauvaise idée de mettre un timeout également sur le flux fopen. C'est utile pour des pages fortement sollicitées sur serveurs paresseux!
Deuxiemement ce n'est pas un frameset mais une redirection... Et comme je le disais je souhaite utilise l'adresse de redirection dans mon script plutot que l'ip réelle du serveur...
Voici le contenu de ta page:

Code : Tout sélectionner

<frameset rows="100%,*" cols="100%" framespacing="0" frameborder="no" border="0"> <frame name="RegisterSite" scrolling="auto" src="http://xxx.xxx.xx.xxx/~nukeclan/NCversion.txt" noresize> <noframes> Please go to: <a href="http://xxx.xxx.xx.xxx/~nukeclan/NCversion.txt">http://xxx.xxx.xx.xxx/~nukeclan/NCversion.txt</a> </noframes> </frameset>
Une "redirection" html, pas http (code de réponse http 3xx). Or les flux de manipulation de fichiers sur adresses distantes ne seront redirigés automatiquement qu'avec les redirections http.

Dans ce cas je ne vois pas trop comment faire autrement que de capturer le contenu de ta page html, et d'en extraire par regex l'adresse de la "redirection". Et de refaire un fopen ou file_get_contents sur la nouvelle adresse.

C'est quoi le côté non sécurisé de mettre l'IP directement dans ton script. C'est une entrée utilisateur ?
ripat

Eléphanteau du PHP | 43 Messages

25 déc. 2005, 11:35

Donc il me faudrait rajouter un timeout sur le fopen...

A ouais cette arnaque c'te redirection!!!

Le probleme c'est que le script va etre disponible au public...

P.S : merci pour les xxx

ViPHP
ViPHP | 1380 Messages

25 déc. 2005, 11:51

Donc il me faudrait rajouter un timeout sur le fopen...
Pas indispensable pour ton problème, mais utile. Une sécutité supplémentaire au cas où...
A ouais cette arnaque c'te redirection!!!
Ben oui. Je ne fais pas partie des fanatiques anti-frames (quoique...) mais il faut admettre que dans ce cas, ils auraient raison de brûler l'auteur de cette "redirection" sur le bûcher des standards :wink:

Le html c'est pour structurer un document. Tout ce qui concerne le "service" des pages, il convient de le laisser au serveur http. Je viens de jeter un oeil sur la doc CURL. Et ils font la même réponse.
http://curl.haxx.se/mail/archive-2002-12/0073.html

Il te reste les regex pour capturer la redirection et refaire un fopen.
ripat

Eléphanteau du PHP | 43 Messages

25 déc. 2005, 20:12

Ok merci je vais essailler le timeout sur le fopen

Je ne connais pas du tout le CURL ni le regex... :roll:

ViPHP
ViPHP | 1380 Messages

26 déc. 2005, 10:17

Ok merci je vais essailler le timeout sur le fopen

Je ne connais pas du tout le CURL ni le regex... :roll:
Tu sais, n'importe qui peut trouver facilement l'adresse IP qui se cache derrière la "redirection" par frameset.

Mais bon, allez, c'est Noël après tout :wink:

Ma fonction monFileGetContents fait exactement ce que fait file_get_contents sur des fichiers distants mais avec un timeout sur le socket ET la lecture du fichier. Elle est même (beaucoup) plus rapide que file_get_contents.
function monFileGetContents($adresse, $timeout = 10){
  $url = parse_url($adresse);
  $url['port']   = isset($url['port'])   ? $url['port']               : '80';
  $url['scheme'] = isset($url['scheme']) ? strtoupper($url['scheme']) : 'HTTP';
  $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, $timeout);
  if (!$fp) {
    echo "ERREUR: $errno - $errstr<br />\n";
  } else {
    $header  = 'GET '.$url['path'].' '.$url['scheme']."/1.1\r\n";
    $header .= 'Host: '.$url['host']."\r\n";
    $header .= "User-Agent: monPHP Script\r\n";
    $header .= "Connection: Close\r\n\r\n";
    fputs($fp, $header);
    stream_set_timeout($fp, $timeout);
    $page    = fread($fp, 2000);
    $stream  = stream_get_meta_data($fp);
    fclose($fp);    
    if ($stream['timed_out']) {
      echo "Le délai de réponse de la page <b>".$adresse.
      '</b> a dépassé le timeout de <b>'.$timeout.'</b> sec.';
      return false;
    }else{
      /* //Pour debugging: echo des headers
        echo '<pre>'.$header;
        echo substr($page, 0, strpos($page, "\r\n\r\n"));
        echo '</pre>';
      */
      // séparation du header
      $page = substr($page, strpos($page, "\r\n\r\n"));
      $page = trim($page);
      return $page;
    }
  }
}


// ouverture de la page demandée
$page = monFileGetContents("http://www.nukeclan.org/NCversion.txt", 5);
// pour voir le contenu du frameset décommenter la ligne suivante
// echo htmlentities($page);

// détection de la "redirection" html par frameset
preg_match('#Please go to: <a href="([^"]*)">#', $page, $out);
$redirection = $out[1];

// simple file_get_contents sur la redirection
$NCverout = file_get_contents($redirection);
echo $NCverout;
Mais, encore une fois, ce serait plus simple d'utiliser directement l'IP dans un fopen ou file_get_contents. Tu allègera sensiblement le code.

Si tu veux ajouter le confort d'un timeout sur le flux, utilise ma fonction monFileGetContents mais directement sur l'adresse IP du fichier.
ripat

Eléphanteau du PHP | 43 Messages

26 déc. 2005, 14:08

Merci PAPA NOEL :wink: :lol:

Je test et te tient au courant

Merci encore