diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 7264c83b152..2b98bac30c6 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -114,6 +114,9 @@ class FormFile if (empty($usewithoutform)) // Try to avoid this and set instead the form by the caller. { + // Add a param as GET parameter to detect when POST were cleaned by PHP because a file larger than post_max_size + $url .= (strpos('?', $url) === false ? '?' : '&').'uploadform=1'; + $out .= '
'; $out .= ''; $out .= ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4fe156b249b..25b67455d70 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8919,3 +8919,45 @@ function addSummaryTableLine($tableColumnCount, $num, $nbofloop = 0, $total = 0, print ''; } + +/** + * Return a file on output using a lo memory. + * It can return very large files with no need of memory. + * + * @param string $fullpath_original_file_osencoded Full path of file to return. + * @param int $method -1 automatic, 0=readfile, 1=fread, 2=stream_copy_to_stream + */ +function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) +{ + global $conf; + + if ($method == -1) { + $method = 0; + if (! empty($conf->global->MAIN_FORCE_READFILE_WITH_FREAD)) $method = 1; + if (! empty($conf->global->MAIN_FORCE_READFILE_WITH_STREAM_COPY)) $method = 2; + } + + // Solution 0 + if ($method == 0) { + // Be sure we don't have output buffering enabled to have readfile working correctly + while (ob_get_level()) ob_end_flush(); + + readfile($fullpath_original_file_osencoded); + } + // Solution 1 + elseif ($method == 1) { + $handle = fopen($fullpath_original_file_osencoded, "rb"); + while (!feof($handle)) { + print fread($handle, 8192); + } + fclose($handle); + } + // Solution 2 + elseif ($method == 2) { + $handle1 = fopen($fullpath_original_file_osencoded, "rb"); + $handle2 = fopen("php://output", "wb"); + stream_copy_to_stream($handle1, $handle2); + fclose($handle1); + fclose($handle2); + } +} diff --git a/htdocs/document.php b/htdocs/document.php index ab3ad20a8f8..bc0cc1eb933 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -261,10 +261,11 @@ if (!$attachment && !empty($conf->global->MAIN_USE_EXIF_ROTATION) && image_forma $readfile = !$imgres; } +if (is_object($db)) $db->close(); + +// Send file now if ($readfile) { header('Content-Length: '.dol_filesize($fullpath_original_file)); - readfile($fullpath_original_file_osencoded); + readfileLowMemory($fullpath_original_file_osencoded); } - -if (is_object($db)) $db->close(); diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1344287044e..ef7b5e33a7d 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -378,10 +378,18 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->gl in_array(GETPOST('action', 'aZ09'), array('add', 'addtimespent', 'update', 'install', 'delete', 'deleteprof', 'deletepayment'))) { if (!GETPOSTISSET('token')) { - dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused by CSRFCHECK_WITH_TOKEN protection. Token not provided."); - print "Access to this page this way (POST method or page with CSRFCHECK_WITH_TOKEN on or having a sensible value for action parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n"; - print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n"; - die; + if (GETPOST('uploadform')) { + dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused. File size too large."); + $langs->loadLangs(array("errors", "install")); + print $langs->trans("ErrorFileSizeTooLarge").' '; + print $langs->trans("ErrorGoBackAndCorrectParameters"); + die; + } else { + dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." refused by CSRFCHECK_WITH_TOKEN protection. Token not provided."); + print "Access to this page this way (POST method or page with CSRFCHECK_WITH_TOKEN on or having a sensible value for action parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n"; + print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n"; + die; + } } }