2015-01-17 15 views
8

파일을 업로드하는 데 Plupupload을 사용하고 있습니다. IE9로 exe을로드하려고 시도하고 파일 크기가 upload_max_filesize 또는 post_max_size 이상인 경우 업로드 된 파일이 손상되었습니다.PHP/Javascript 청크 업로드 : 파일 크기가 upload_max_filesize 또는 post_max_size 이상인 경우 IE9 파일이 손상됩니다.

<?php 
/** 
* upload.php 
* 
* Copyright 2013, Moxiecode Systems AB 
* Released under GPL License. 
* 
* License: http://www.plupload.com/license 
* Contributing: http://www.plupload.com/contributing 
*/ 

// Make sure file is not cached (as it happens for example on iOS devices) 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false); 
header("Pragma: no-cache"); 

// 5 minutes execution time 
@set_time_limit(5 * 60); 

// Settings 
$targetDir = __DIR__ . DIRECTORY_SEPARATOR . "upload"; 

// Create target dir 
if (!file_exists($targetDir)) { 
    @mkdir($targetDir); 
} 

// Get a file name 
if (isset($_REQUEST["name"])) { 
    $fileName = $_REQUEST["name"]; 
} elseif (!empty($_FILES)) { 
    $fileName = $_FILES["file"]["name"]; 
} else { 
    $fileName = uniqid("file_"); 
} 

$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; 

// Chunking might be enabled 
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; 
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; 


// Open temp file 
if (!$out = @fopen("{$filePath}.part", $chunks ? "ab" : "wb")) { 
    die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); 
} 

if (!empty($_FILES)) { 
    if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) { 
     die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); 
    } 

    // Read binary input stream and append it to temp file 
    if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) { 
     die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); 
    } 
} else {  
    if (!$in = @fopen("php://input", "rb")) { 
     die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); 
    } 
} 

while ($buff = fread($in, 4096)) { 
    fwrite($out, $buff); 
} 

@fclose($out); 
@fclose($in); 

// Check if file has been uploaded 
if (!$chunks || $chunk == $chunks - 1) { 
    // Strip the temp .part suffix off 
    rename("{$filePath}.part", $filePath); 
} 

// Return Success JSON-RPC response 
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); 

업로드는 HTML 페이지를 통해 발생합니다 :

이 내가 사용하고있는 PHP 스크립트입니다

내가 notepad++로를 열려고하면 exe이, 부패
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 

<title>Plupload - Custom example</title> 

<!-- production --> 
<script type="text/javascript" src="../js/plupload.full.min.js"></script> 

</head> 
<body style="font: 13px Verdana; background: #eee; color: #333"> 

<h1>Custom example</h1> 

<p>Shows you how to use the core plupload API.</p> 

<div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div> 
<br /> 

<div id="container"> 
    <a id="pickfiles" href="javascript:;">[Select files]</a> 
    <a id="uploadfiles" href="javascript:;">[Upload files]</a> 
</div> 

<br /> 
<pre id="console"></pre> 


<script type="text/javascript"> 
// Custom example logic 

var uploader = new plupload.Uploader({ 
    runtimes : 'html5,flash,silverlight,html4', 
    browse_button : 'pickfiles', // you can pass in id... 
    container: document.getElementById('container'), // ... or DOM Element itself 
    url : 'upload.php', 
    flash_swf_url : '../js/Moxie.swf', 
    silverlight_xap_url : '../js/Moxie.xap', 
    chunk_size : '2mb', 

    filters : { 
     max_file_size : '100mb', 
     mime_types: [ 
      {title : "Image files", extensions : "jpg,gif,png"}, 
      {title : "Zip files", extensions : "zip"}, 
      {title : "Exe files", extensions : "exe"} 
     ] 
    }, 

    init: { 
     PostInit: function() { 
      document.getElementById('filelist').innerHTML = ''; 

      document.getElementById('uploadfiles').onclick = function() { 
       uploader.start(); 
       return false; 
      }; 
     }, 

     FilesAdded: function(up, files) { 
      plupload.each(files, function(file) { 
       document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>'; 
      }); 
     }, 

     UploadProgress: function(up, file) { 
      document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; 
     }, 

     Error: function(up, err) { 
      document.getElementById('console').innerHTML += "\nError #" + err.code + ": " + err.message; 
     } 
    } 
}); 

uploader.init(); 

</script> 
</body> 
</html> 

, 내가 찾은 :

enter image description here

내 설정 :

PHP Version 5.5.9 
System   Windows NT PC-XXX 6.0 build 6002 (Windows Vista Service Pack 2) i586 
Compiler  MSVC11 (Visual C++ 2012) 
Architecture x86 
Server API  Apache 2.0 Handler 

php.ini의

max_execution_time=30 
max_input_time=60 
memory_limit=128M 
max_file_uploads=20 

추가 정보를 원하시면

  1. 모든 Plupupload 방법 (HTML5, 플래시, 실버, HTML4) 문제를 가지고
  2. 안티 바이러스 비활성화
  3. UAC가 비활성화 됨

TRY 이슈 너 자신 나는 시도하고 싶은 사람을위한 패키지를 만든

.

다운로드 패키지 : http://www.sndesign.it/shared/stackoverflow/plupload-2.1.2.zip

plupload-2.1.2.zip 또한 plupload-2.1.2/examples/upload/file_54c4c1d05c2ef 폴더와 파일의 손상된 업로드 파일이 plupload-2.1.2/examples/TryMe.exe

테스트 (나는 XAMPP Version 1.8.3 사용)을 준비 업로드하려고 할 포함

  1. htdocs
  2. 세트에 plupload-2.1.2.zip을 압축 해제하십시오. 0864909886upload_max_filesize=22Mpost_max_size=22M (TryMe.exe 파일 크기 23메가바이트에 이하), 아파치
  3. 열기 IE9을 (IE9은 항상 실패)를 다시 시작하고, 이동 : %YourHtdocs%/plupload-2.1.2/examples/TryMe.exehttp://localhost/plupload-2.1.2/examples/custom.html
  4. 파일을 선택하고 %YourHtdocs%/plupload-2.1.2/examples/upload/
  5. 이동을 업로드하고 찾을 파일 업로드
  6. 업로드 된 파일이 손상되었습니다.
  7. 세트 php.iniupload_max_filesize=24Mpost_max_size=24M (최대 TryMe.EXE 파일 크기 23메가바이트)는 %YourHtdocs%/plupload-2.1.2/examples/TryMe.exe에 아파치
  8. 파일 선택을 다시 시작하고
  9. %YourHtdocs%/plupload-2.1.2/examples/upload/에 가서 업로드 된 파일이 괜찮 업로드 된 파일
  10. 을 찾아 업로드합니다.
+0

@maytham은 개발자가 업로드 한 인디 소프트웨어를 수집하는 서비스입니다. –

+0

@maytham 어떤 종류의 문제가 있습니까? 나는 이미지와 지퍼로 시험해보고 잘 작동한다. –

+0

@maytham [github plupupload project] (https://github.com/moxiecode/plupload/issues/1193)에서도 문제를보고했다. 계속 지켜봐주십시오, 어쩌면 누군가가 해결책을 찾았습니다. –

답변

2

기본적으로 PHP 최대 업로드 파일 크기는 2MB로 설정됩니다.

upload_max_filesize = 20M 
post_max_size = 22M 

더 많은 정보는 : http://php.net/manual/en/ini.core.php#ini.upload-max-filesizehttp://php.net/manual/en/ini.core.php#ini.post-max-size

+0

유의 사항 당신은 설정을 적용하기 전에 아파치 서버를 다시 시작해야한다. (그렇지 않다면) –

+0

Ah, 나는 또한 당신이 plupload를 인스턴스화 할 때 "chunk_size"를 정의하지 않았다는 것을 당신의 포스트에서 알아 차렸다. –

+0

다른 대형 EXE 파일을 사용해 보셨나요? 이 문제에 영향을 줄 수있는 백그라운드 프로세스 (안티 바이러스, 작업 등)가 있는지 알고 있습니까? 난 그냥 방해가 되길 원해. –

3

우리가 알고있는 것은, 온전한 파일을 청크로 분할되어있는 각이

는 PHP를 설정 (php.ini 파일)을 업데이트하십시오 HTTP multipart/form-data 헤더와 Content-Disposition 헤더를 접두사로 붙입니다. 첫 번째 것은 항상 올바르게 제거되며 두 번째는 제거되지 않습니다.
이 3 가능성으로 우리를 잎 : 파일이 전송 될 때 헤더의

  1. 적어도 하나가 손상되었습니다.
  2. 적어도 하나의 헤더가 브라우저에 의해 전송 된 후 손상되었지만 PHP에 의해 구문 분석되기 전에 손상되었습니다.
  3. PHP가 요청을 구문 분석하는 동안 문제가 발생합니다.

위의 원인 중 일부는 방화벽, 바이러스 백신 또는 다른 이유로 인해 네트워크 트래픽이나 RAM/파일 시스템 작업을 거쳐야하는 다른 서비스에 의한 파괴적인 필터링 일 수 있습니다. 1.의 경우 브라우저/JavaScript/Flash/Silverlight/PlUpload 엔진의 버그 일 수도 있습니다. 의 경우 2.은 이론적으로 Apache를 망쳐 놓을 수 있지만 PHP로 데이터 1 : 1을 전달하기 때문에 극히 드문 것입니다. 이제 3.에 대해 PHP에서 버그를 배제 할 수는 없지만 PHP가 여기에 상수이고 브라우저마다 결과가 다르기 때문에 너무 극히 드뭅니다. 하지만 PHP는 파일을 받았다고 생각하고, 두 번째 헤더와 함께 파일을 저장하고, 일부 서비스가 필터링을하기 때문에 파일을 잠근 것으로 생각할 수 있습니다. 파일이 신뢰할 수 없거나 크기가 커서 필터링이 오래 걸립니다. PHP는 두 번째 헤더를 제거하려고 시도하지만 액세스가 거부됩니다. 필터링이 계속 진행 중이고 끝에 헤더가있는 파일이 남아 있기 때문입니다. 브라우저마다 다른 결과는 여러 청크 크기 또는 단순히 브라우저 성능으로 설명 할 수 있습니다.

불행히도, 그것은 모두 추측입니다. 이제 마이크로 소프트는 IE를 다운 그레이드하기 위해 최대한 열심히 노력했기 때문에 현재 IE9로 테스트 할 수 없습니다. 디버깅 지침이 있습니다.

php.ini에서

enable_post_data_reading = Off 

이렇게하면 해당 서버의 모든 POST 요청이 완전히 중단되지만 파일 업로드 요청을 읽고 덤프 할 수 있습니다.

file_put_contents('out.txt', print_r(getallheaders(), true).PHP_EOL.substr(file_get_contents('php://input'), 0, 1000), FILE_APPEND); 
exit; 

시작 아파치와 IE9와 TryMe.exe을 업로드 : 당신의 upload.php로에서

, 다른 코드 앞에 두 줄을 추가합니다. 이제 upload.php 옆에는 파일 업로드 요청에 대한 모든 관련 데이터가 들어있는 out.txt 파일이 있어야합니다. 해당 파일을 어딘가에 업로드하고 링크를 보내주십시오.

+0

도움을 주셔서 감사합니다. 출력 파일 http://www.sndesign.it/shared/stackoverflow/out.txt를 다운로드 할 수 있습니다. –

+0

음, ** [this] (http://pastebin.com/KerXq6Wh) ** IE11의 결과,'chunk'와'chunks' 섹션이 어떻게 사라 졌는지 주목하십시오. IE9에서 작동하는 파일을 업로드 할 때 덤프를 줄 수 있습니까? – Siguza

+0

mhhh IE9는 파일 크기가 매우 작을 때만 작동합니다 ... –