diff --git a/ecrire/action/charger_plugin.php b/ecrire/action/charger_plugin.php
index db3862df9062a3b76270837006f19c9d4f2887bb..de922a14c3614428fb568e72d4e3b16311112deb 100644
--- a/ecrire/action/charger_plugin.php
+++ b/ecrire/action/charger_plugin.php
@@ -75,10 +75,8 @@ function action_charger_plugin_dist() {
 	$fichier = $tmp.basename($zip);
 	if (!@file_exists($fichier)) {
 		include_spip('inc/distant');
-		$contenu = recuperer_page($zip, false, false,
-			8000000 /* taille max */);
-		if (!$contenu
-		OR !ecrire_fichier($fichier, $contenu)) {
+		$contenu = recuperer_page($zip, $fichier, false,_COPIE_LOCALE_MAX_SIZE);
+		if (!$contenu) {
 			spip_log('charger_decompresser impossible de charger '.$zip);
 			$status = -1;
 		}
diff --git a/ecrire/inc/distant.php b/ecrire/inc/distant.php
index 87e0af9768fa126873e58f70d06328d548232db8..33c4c3d4cf9c9709a246f50722c3d764840dabf6 100644
--- a/ecrire/inc/distant.php
+++ b/ecrire/inc/distant.php
@@ -46,15 +46,9 @@ function copie_locale($source, $mode='auto') {
 	AND preg_match(',^\w+://,', $source)) {
 		if (($mode=='auto' AND !@file_exists(_DIR_RACINE.$local))
 		OR $mode=='force') {
-			$contenu = recuperer_page($source,false,false,_COPIE_LOCALE_MAX_SIZE);
-			if (!$contenu) return false;
-			if (preg_match(',[.](jpg|gif|png)$,i',$local) 
-			  AND strlen($contenu)>_COPIE_LOCALE_MAX_SIZE){
-			  spip_log ('ERREUR copie locale image '._DIR_RACINE.$local.' superieure a  '._COPIE_LOCALE_MAX_SIZE);
-			  return false;
-			}
-			ecrire_fichier(_DIR_RACINE.$local, $contenu);
-			spip_log ('ecrire copie locale '._DIR_RACINE.$local);
+			$res = recuperer_page($source,_DIR_RACINE.$local,false,_COPIE_LOCALE_MAX_SIZE);
+			if (!$res) return false;
+			spip_log ('ecrire copie locale '._DIR_RACINE.$local." taille $res");
 			
 			// pour une eventuelle indexation
 			pipeline('post_edition',
@@ -161,12 +155,17 @@ function prepare_donnees_post($donnees, $boundary = '') {
 // et refuser_gz pour forcer le refus de la compression (cas des serveurs orthographiques)
 // date_verif, un timestamp unix pour arreter la recuperation si la page distante n'a pas ete modifiee depuis une date donnee
 // uri_referer, preciser un referer different
+// si munge_charset est une chaine, alors c'est un nom de fichier
+// dans lequel on ecrit directement la page
 // http://doc.spip.org/@recuperer_page
 function recuperer_page($url, $munge_charset=false, $get_headers=false,
-	$taille_max = 1048576, $datas='', $boundary='', $refuser_gz = false,
+	$taille_max = null, $datas='', $boundary='', $refuser_gz = false,
 	$date_verif = '', $uri_referer = '') {
-  	$gz = false;
-  // Accepter les URLs au format feed:// ou qui ont oublie le http://
+	$gz = false;
+	if (is_null($taille_max))
+		$taille_max = is_string($munge_charset)?_COPIE_LOCALE_MAX_SIZE:1048576;
+
+	// Accepter les URLs au format feed:// ou qui ont oublie le http://
 	$url = preg_replace(',^feed://,i', 'http://', $url);
 	if (!preg_match(',^[a-z]+://,i', $url)) $url = 'http://'.$url;
 
@@ -194,10 +193,16 @@ function recuperer_page($url, $munge_charset=false, $get_headers=false,
 
 // args comme ci-dessus (presque)
 // retourne l'URL en cas de 301, un tableau (entete, corps) si ok, false sinon
-
+// si $trans est null -> on ne veut que les headers
+// si $trans est une chaine, c'est un nom de fichier pour ecrire directement dedans
 // http://doc.spip.org/@recuperer_lapage
 function recuperer_lapage($url, $trans=false, $get='GET', $taille_max = 1048576, $datas='', $boundary='', $refuser_gz = false, $date_verif = '', $uri_referer = '')
 {
+	// si on ecrit directement dans un fichier, 
+	// pour ne pas manipuler en memoire
+	// refuser gz
+	if (is_string($trans) AND $trans)
+		$refuser_gz = true;
 	// ouvrir la connexion et envoyer la requete et ses en-tetes
 	list($f, $fopen) = init_http($get, $url, $refuser_gz, $uri_referer, $datas);
 	if (!$f) {
@@ -226,7 +231,7 @@ function recuperer_lapage($url, $trans=false, $get='GET', $taille_max = 1048576,
 
 #	spip_log("recup  $headers" );
 	if ($trans === NULL) return array($headers, '');
-	$result = recuperer_body($f, $taille_max);
+	$result = recuperer_body($f, $taille_max,is_string($trans)?$trans:'');
 	fclose($f);
 	if (!$result) return array($headers, $result);
 
@@ -235,7 +240,7 @@ function recuperer_lapage($url, $trans=false, $get='GET', $taille_max = 1048576,
 		$result = spip_gzinflate_body($result);
 	}
 	// Faut-il l'importer dans notre charset local ?
-	if ($trans) {
+	if ($trans===true) {
 		include_spip('inc/charsets');
 		$result = transcoder_page ($result, $headers);
 	}
@@ -268,11 +273,27 @@ function spip_gzinflate_body($gzData){
 
 
 // http://doc.spip.org/@recuperer_body
-function recuperer_body($f, $taille_max=1048576)
+function recuperer_body($f, $taille_max=1048576, $fichier='')
 {
+	$taille = 0;
 	$result = '';
-	while (!feof($f) AND strlen($result)<$taille_max)
-		$result .= fread($f, 16384);
+	if ($fichier){
+		$fp = spip_fopen_lock($fichier, 'w',LOCK_EX);
+		if (!$fp) return false;
+		$result = 0; // on renvoie la taille du fichier
+	}
+	while (!feof($f) AND $taille<$taille_max){
+		$res = fread($f, 16384);
+		$taille += strlen($res);
+		if ($fp){
+			fwrite($fp,$res);
+			$result = $taille;
+		}
+		else
+			$result .= $res;
+	}
+	if ($fp)
+		spip_fclose_unlock($fp);
 	return $result;
 }
 
@@ -354,6 +375,7 @@ function fichier_copie_locale($source) {
 	$path_parts = pathinfo($source);
 	$ext = $path_parts ? $path_parts['extension'] : '';
 	if ($ext
+		AND preg_match(',^\w+$,',$ext) // pas de php?truc=1&...
 	  AND $f=nom_fichier_copie_locale($source, $ext)
 	  AND file_exists(_DIR_RACINE . $f))
 	  return $f;
diff --git a/ecrire/inc/math.php b/ecrire/inc/math.php
index 2c49b6cedad47586b47018d3e54baf73303a8c0f..fc6eaaf0a6851c422f5290e93fdea4b79215e7c8 100644
--- a/ecrire/inc/math.php
+++ b/ecrire/inc/math.php
@@ -46,12 +46,7 @@ function produire_image_math($tex) {
 		if ($server) {
 			spip_log($url = $server.'?'.rawurlencode($tex));
 			include_spip('inc/distant');
-			if ($image = recuperer_page($url)) {
-				if ($f = @fopen($fichier, 'w')) {
-					@fwrite($f, $image);
-					@fclose($f);
-				}
-			}
+			recuperer_page($url,$fichier);
 		}
 	}
 
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index 8208a1d74dcb1ee3f249f46b0423ca14a3d97652..849d09fd749c5b21d80fd3fc50bde5684ad72faa 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -1290,7 +1290,7 @@ function spip_initialisation_suite() {
 	define('_IMG_MAX_WIDTH', 0); # largeur en pixels
 	define('_IMG_MAX_HEIGHT', 0); # hauteur en pixels
 
-	define('_COPIE_LOCALE_MAX_SIZE',2097152); // poids en octet
+	define('_COPIE_LOCALE_MAX_SIZE',16777216); // poids en octet
 
 	// qq chaines standard
 	define('_ACCESS_FILE_NAME', '.htaccess');