From: Dipartimento I. Jobiz.c. <ic...@jo...> - 2004-11-30 07:44:10
|
Hi As you suggestion i write the diff files of "patch" and publish it on=20 this ML .... As you say "How can you guarantee that you are only stripping off the=20 correct number of newlines? " the solution is simple: I wrote an autogenerating php page "on the fly"=20 with download informations only, after, i redirect SM on it,in this=20 manner, i precisely define the content i write on download channel and=20 avoid strange "unpredictable" behaviours that can come out from other=20 sections of program ( plugins, etc ... ). At the end of download=20 temporary files are removed in order to avoid to fill directory with=20 useless files.In this manner, IMHO, SM appear to be less prone to these=20 "side effects" and, think, this patch to be considered as "version=20 independent" if you consider that it creates and destroy itself without=20 involve any part of SM. Don't worry for multi user environment : temporary files are named with=20 session cookie value so, think, they are uniques and don't conflict=20 with various users downloads.Multiple download from same user =20 generating, of course, the same file name, but this isn't a problem:=20 user can download one file at once ... WARNING !!! : In a very ugly manner i've 'Hard coded' ( is a nightly=20 build ... ) a path to a directory that contains temporary working files=20 the path for my installation is '/var/www/webmail/data' so you MUST=20 change this with your own directory were squirrel user can write/read (=20 for me user is : nobody/nobody ) this can be solved using a global=20 variable .... Thanks to you and other people that have send kindly suggestions to me... With regards Mariano -------------------------------------------------------------------------= ----------------------- Diff file for Download.php -------------------------------------------------------------------------= ----------------------- --- download.php 2003-09-12 00:06:50.000000000 +0000 +++ download.php 2004-11-25 08:54:54.000000000 +0000 @@ -20,11 +20,20 @@ require_once(SM_PATH . 'functions/imap.php'); require_once(SM_PATH . 'functions/mime.php'); =20 -header('Pragma: '); -header('Cache-Control: cache'); +//header('Pragma: '); +//header('Cache-Control: cache'); =20 /* globals */ sqgetGlobalVar('key', $key, SQ_COOKIE); + +/* Code Patched by Mariano Mancini + * Using SQMSESSID to compose filenames for the patch .... + * so i extract it ... Excuse for the variable name $sessione i use it=20 in Italian to avoid to overlap English + * variable with same name + */ + +sqgetGlobalVar('SQMSESSID', $sessione, SQ_COOKIE); + sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION); sqgetGlobalVar('messages', $messages, SQ_SESSION); @@ -37,6 +46,74 @@ =20 /* end globals */ =20 +/* + * This function is verified to work with Netscape and the *very latest* + * version of IE. I don't know if it works with Opera, but it should no= w. + */ +function DumpHeaders($type0, $type1, $filename, $force) { + global $languages, $squirrelmail_language; + $isIE =3D $isIE6 =3D 0; + + sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER); + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !=3D=3D false && + strstr($HTTP_USER_AGENT, 'Opera') =3D=3D=3D false) { + $isIE =3D 1; + } + + if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !=3D=3D false && + strstr($HTTP_USER_AGENT, 'Opera') =3D=3D=3D false) { + $isIE6 =3D 1; + } + + if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && + function_exists($languages[$squirrelmail_language]['XTRA_CODE'])= ) { + $filename =3D + =20 $languages[$squirrelmail_language]['XTRA_CODE']('downloadfilename',=20 $filename, $HTTP_USER_AGENT); + } else { + $filename =3D ereg_replace('[\\/:\*\?"<>\|;]', '_',=20 str_replace(' ', ' ', $filename)); + } + + // A Pox on Microsoft and it's Office! + if (!$force) { + // Try to show in browser window + header("Content-Disposition: inline; filename=3D\"$filename\""); + header("Content-Type: $type0/$type1; name=3D\"$filename\""); + } else { + // Try to pop up the "save as" box + // IE makes this hard. It pops up 2 save boxes, or none. + // http://support.microsoft.com/support/kb/articles/Q238/5/88.AS= P + // But, accordint to Microsoft, it is "RFC compliant but doesn't + // take into account some deviations that allowed within the + // specification." Doesn't that mean RFC non-compliant? + // http://support.microsoft.com/support/kb/articles/Q258/4/52.AS= P + // + // The best thing you can do for IE is to upgrade to the latest + // version + if ($isIE && !$isIE6) { + //=20 http://support.microsoft.com/support/kb/articles/Q182/3/15.asp + // Do not have quotes around filename, but that applied to + // "attachment"... does it apply to inline too? + // + // This combination seems to work mostly. IE 5.5 SP 1 has + // known issues (see the Microsoft Knowledge Base) + header("Content-Disposition: inline; filename=3D$filename"); + // This works for most types, but doesn't work with Word fil= es + header("Content-Type: application/download;=20 name=3D\"$filename\""); + + // These are spares, just in case. :-) + //header("Content-Type: $type0/$type1; name=3D\"$filename\""= ); + //header("Content-Type: application/x-msdownload;=20 name=3D\"$filename\""); + //header("Content-Type: application/octet-stream;=20 name=3D\"$filename\""); + } else { + header("Content-Disposition: attachment;=20 filename=3D\"$filename\""); + // application/octet-stream forces download for Netscape + header("Content-Type: application/octet-stream;=20 name=3D\"$filename\""); + } + } +} + + global $uid_support; =20 $imapConnection =3D sqimap_login($username, $key, $imapServerAddress,=20 $imapPort, 0); @@ -91,8 +168,9 @@ } else { $filename =3D $header->getParameter('name'); } - -$filename =3D decodeHeader($filename); +// To avoid strange filenames in download e.g. : 'File Download'=20 instead of 'File Download' +// locking the decodeHeader +//$filename =3D decodeHeader($filename); if (strlen($filename) < 1) { if ($type1 =3D=3D 'plain' && $type0 =3D=3D 'text') { $suffix =3D 'txt'; @@ -132,79 +210,38 @@ * viewer (built in to squirrelmail). Otherwise, it sets the * content-type as application/octet-stream */ -if (isset($absolute_dl) && $absolute_dl) { +/*if (isset($absolute_dl) && $absolute_dl) { DumpHeaders($type0, $type1, $filename, 1); } else { DumpHeaders($type0, $type1, $filename, 0); -} -/* be aware that any warning caused by download.php will corrupt the - * attachment in case of ERROR reporting =3D E_ALL and the output is the= =20 screen */ +}*/ mime_print_body_lines ($imapConnection, $passed_id, $ent_id, $encoding); =20 -/* - * This function is verified to work with Netscape and the *very latest* - * version of IE. I don't know if it works with Opera, but it should no= w. - */ -function DumpHeaders($type0, $type1, $filename, $force) { - global $languages, $squirrelmail_language; - $isIE =3D $isIE6 =3D 0; - - sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER); =20 - if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !=3D=3D false && - strstr($HTTP_USER_AGENT, 'Opera') =3D=3D=3D false) { - $isIE =3D 1; - } +/* Code Patched 19/11/2004 by Mariano Mancini + * Little trick : header statements send 8 LF along the download channe= l + * So i create a single php page with instructions to download file, aft= er + * i destroy files ( download instructions & downloaded file ) to make=20 clean + * the directory and don't waste space on disk with useless files. + * + * WARNING: It's a old dirty trick i hope that SM staff remove this bug=20 quickly .... + * Excuse me for the 'Hard Path' but i nightly developed this snippet + * + * Mariano + */ =20 - if (strstr($HTTP_USER_AGENT, 'compatible; MSIE 6') !=3D=3D false && - strstr($HTTP_USER_AGENT, 'Opera') =3D=3D=3D false) { - $isIE6 =3D 1; - } +$dwname =3D "dw-".$sessione.".php"; +$dwunit =3D "/var/www/webmail/data/dw-".$sessione.".php"; +$atunit =3D "/var/www/webmail/data/at-".$sessione; +$myhnd =3D fopen( $dwunit ,"w"); +fwrite( $myhnd,'<?php'); +fwrite( $myhnd,' '); +fwrite( $myhnd,'header("Content-Disposition: inline;=20 filename=3D\"'.$filename.'\" "); ' ); +fwrite( $myhnd,'header("Content-Type: application/download;=20 name=3D\"'.$filename.'\" "); ' ); +fwrite( $myhnd,'readfile("'.$atunit.'"); '); +fwrite( $myhnd,'unlink("'.$dwunit.'"); unlink("'.$atunit.'"); ' ); +fwrite( $myhnd,' ?>'); +fclose( $myhnd); =20 - if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && - function_exists($languages[$squirrelmail_language]['XTRA_CODE'])= ) { - $filename =3D - =20 $languages[$squirrelmail_language]['XTRA_CODE']('downloadfilename',=20 $filename, $HTTP_USER_AGENT); - } else { - $filename =3D ereg_replace('[\\/:\*\?"<>\|;]', '_',=20 str_replace(' ', ' ', $filename)); - } - - // A Pox on Microsoft and it's Office! - if (!$force) { - // Try to show in browser window - header("Content-Disposition: inline; filename=3D\"$filename\""); - header("Content-Type: $type0/$type1; name=3D\"$filename\""); - } else { - // Try to pop up the "save as" box - // IE makes this hard. It pops up 2 save boxes, or none. - // http://support.microsoft.com/support/kb/articles/Q238/5/88.AS= P - // But, accordint to Microsoft, it is "RFC compliant but doesn't - // take into account some deviations that allowed within the - // specification." Doesn't that mean RFC non-compliant? - // http://support.microsoft.com/support/kb/articles/Q258/4/52.AS= P - // - // The best thing you can do for IE is to upgrade to the latest - // version - if ($isIE && !$isIE6) { - //=20 http://support.microsoft.com/support/kb/articles/Q182/3/15.asp - // Do not have quotes around filename, but that applied to - // "attachment"... does it apply to inline too? - // - // This combination seems to work mostly. IE 5.5 SP 1 has - // known issues (see the Microsoft Knowledge Base) - header("Content-Disposition: inline; filename=3D$filename"); - // This works for most types, but doesn't work with Word fil= es - header("Content-Type: application/download;=20 name=3D\"$filename\""); - - // These are spares, just in case. :-) - //header("Content-Type: $type0/$type1; name=3D\"$filename\""= ); - //header("Content-Type: application/x-msdownload;=20 name=3D\"$filename\""); - //header("Content-Type: application/octet-stream;=20 name=3D\"$filename\""); - } else { - header("Content-Disposition: attachment;=20 filename=3D\"$filename\""); - // application/octet-stream forces download for Netscape - header("Content-Type: application/octet-stream;=20 name=3D\"$filename\""); - } - } -} +header("Location: ../data/".$dwname); ?> -------------------------------------------------------------------------= ----------------------- Diff file for mime.php -------------------------------------------------------------------------= ----------------------- --- mime.php 2004-11-23 15:52:04.000000000 +0000 +++ mime.php 2004-11-25 08:41:55.000000000 +0000 @@ -153,19 +153,13 @@ return $ret; } =20 + function mime_print_body_lines ($imap_stream, $id, $ent_id=3D1, $encodin= g) { global $uid_support; - - /* Don't kill the connection if the browser is over a dialup - * and it would take over 30 seconds to download it. - * Don=B4t call set_time_limit in safe mode. - */ - + global $username; if (!ini_get('safe_mode')) { set_time_limit(0); } - /* in case of base64 encoded attachments, do not buffer them. - Instead, echo the decoded attachment directly to screen */ if (strtolower($encoding) =3D=3D 'base64') { if (!$ent_id) @@ -177,7 +171,23 @@ $query =3D "FETCH $id BODY[$ent_id]"; } =20 - =20 sqimap_run_command($imap_stream,$query,true,$response,$message,$uid_suppo= rt,'sqimap_base64_decode','php://stdout',true); + /* Code Patched 19/11/2004 by Mariano Mancini=20 + * Extract SQMSESSID in order to use it as filename + */ + sqgetGlobalVar('SQMSESSID', $thisSession, SQ_COOKIE); + + /* Change th path /var/www/webmail/data with one valid to your=20 installation + * To be clean : this path can be register as a session variable (=20 in future patch ... ) + */ + =20 + $myhnd =3D fopen("/var/www/webmail/data/at-".$thisSession,"a"); + // original one, some people say 'writing on php://stdout contain a=20 failure, it's not really a file stream' + // I don't know if it's real but in case .... + //=20 sqimap_run_command($imap_stream,$query,true,$response,$message,$uid_suppo= rt,'sqimap_base64_decode','php://stdout',true); + =20 sqimap_run_command($imap_stream,$query,true,$response,$message,$uid_suppo= rt,'sqimap_base64_decode',$myhnd,true); + fclose($myhnd); + /* End of patch */ + =20 } else { @@ -188,11 +198,9 @@ } =20 function sqimap_base64_decode(&$string) { - - //$string =3D base64_decode($string); - //$string =3D str_replace("\r\n", "\n", $string); + $string =3D str_replace("\r\n", "\n", $string); $string =3D base64_decode($string); - + return $string; } |