2010-07-20 9 views
3

웹 사이트가 두 개 있습니다. 하나는 Lighttpd이고 다른 하나는 Apache이고 다른 하나는 청크 분할 전송 인코딩을 제대로 처리하지 못합니다.청크 인코딩 요청을 올바르게 처리하는 방법은 무엇입니까?

본인은 모바일, J2ME로부터이 요청을 보내고이 전송 유형을 다른 것으로 변경할 가능성이 없습니다.

내 유일한 방법은 다른 방식으로 청크 분할 된 전송 된 enconcoded 요청을 처리하는 것입니다. 필요한 모든 것을 설치하고 변경할 수있는 CentOS 서버에서 사용할 수있는 한 모든 솔루션이 유용 할 것입니다.

내 질문은 : 서버 쪽에서 청크 인코딩 요청을 올바르게 처리하는 방법은 무엇입니까?

답변

5

편집 : 실행중인 PHP/Apache/LightHTTP 버전은 무엇입니까? 이전에는 PHP에 this bug이 있었지만, 5.2.13과 5.3.2는 없어 보입니다.

위의 링크가 도움이되지 않는다면, 나는 PHP가 무엇을보고 있는지 정확히 알고 싶습니다. 이것을 API에 넣고 결과를 게시 할 수 있습니까? (물론 편집 됨).

$input = file_get_contents('php://input'); 
$stdin = file_get_contents('php://stdin'); 

print "FILES: "; 
print_r($_FILES); 

print("<br>POST: "); 
print_r($_POST); 

print("<br>input: ".$input); 
print("<br>stdin: ".$stdin); 
die; 

이렇게하면 PHP가 보는 내용을 볼 수 있으며, 청크 분할 인코딩을 디코딩하지 않으면 수동으로 디코딩 할 수 있습니다.

End EDIT. (다른 사람이 유용하다고 생각 될 경우를 대비하여 아래에 남겨 두십시오)

나는이 질문이 귀하의 이전 질문에 대한 후속 조치라고 가정합니다. 그리고 PHP에서 스트림을 읽고 있다고 가정하고 있습니까?

나는 이것을 몇백 년 전으로 썼다. 청크 인코딩 된 스트림에서 읽었을 때 출력으로 원하는 모든 것을 할 수있다. 큰 파일 인 경우 문자열로 읽지 않고 대신 파일에 쓰십시오.

<?php 
define('CRLF', "\r\n"); 
define('BUFFER_LENGTH', 8192); 
$headers = ''; 
$body = ''; 
$length = 0; 

$fp = fsockopen($host, $port, $errno, $errstr, $timeout); 

// get headers FIRST 
do 
{ 
    // use fgets() not fread(), fgets stops reading at first newline 
    // or buffer which ever one is reached first 
    $data = fgets($fp, BUFFER_LENGTH); 
    // a sincle CRLF indicates end of headers 
    if ($data === false || $data == CRLF || feof($fp)) { 
     // break BEFORE OUTPUT 
     break; 
    } 
    $headers .= $data; 
} 
while (true); 
// end of headers 

// read from chunked stream 
// loop though the stream 
do 
{ 
    // NOTE: for chunked encoding to work properly make sure 
    // there is NOTHING (besides newlines) before the first hexlength 

    // get the line which has the length of this chunk (use fgets here) 
    $line = fgets($fp, BUFFER_LENGTH); 

    // if it's only a newline this normally means it's read 
    // the total amount of data requested minus the newline 
    // continue to next loop to make sure we're done 
    if ($line == CRLF) { 
     continue; 
    } 

    // the length of the block is sent in hex decode it then loop through 
    // that much data get the length 
    // NOTE: hexdec() ignores all non hexadecimal chars it finds 
    $length = hexdec($line); 

    if (!is_int($length)) { 
     trigger_error('Most likely not chunked encoding', E_USER_ERROR); 
    } 

    // zero is sent when at the end of the chunks 
    // or the end of the stream or error 
    if ($line === false || $length < 1 || feof($fp)) { 
     // break out of the streams loop 
     break; 
    } 

    // loop though the chunk 
    do 
    { 
     // read $length amount of data 
     // (use fread here) 
     $data = fread($fp, $length); 

     // remove the amount received from the total length on the next loop 
     // it'll attempt to read that much less data 
     $length -= strlen($data); 

     // PRINT out directly 
     #print $data; 
     #flush(); 
     // you could also save it directly to a file here 

     // store in string for later use 
     $body .= $data; 

     // zero or less or end of connection break 
     if ($length <= 0 || feof($fp)) 
     { 
      // break out of the chunk loop 
      break; 
     } 
    } 
    while (true); 
    // end of chunk loop 
} 
while (true); 
// end of stream loop 

// $body and $headers should contain your stream data 
?> 
+0

PHP에서 스트림을 읽지 않지만 PHP 스크립트는 청크 POST 호출로 호출됩니다. 이 POST 호출의 스트림을 읽는 방법? 아마 아십니까? –

+0

J2ME이 PHP 스크립트를 호출하고 청크 분할 인코딩 결과를 기대하고 있으며 아파치와 lighthttpd가 청크 인코딩을 제대로 전송하지 못하고 있습니까? PHP 스크립트는 청크로 인코딩 된 블록으로 데이터를 써야합니다. 1 API는 2 공정을 3. 출력 버퍼링 4. 에러를 개시 또는 유효한 데이터 제 송신 CORRECT 헤더 세륨 5. 버퍼 처리하는 버퍼에 수집하고 변환 된 결과를 호출된다 7 . 청크 인코딩 된 데이터를 보냅니다. 이미 작성된 코드가 없으므로 온라인에서 뭔가를 찾을 수 있습니까? 그렇지 않다면 클래스를 만드는 것이 어렵지 않습니다. –

+0

다음과 같이 보입니다. J2ME은 청크 분할 인코딩을 apache 또는 lighttpd에 보내고 두 서버는이 요청을 올바르게 수신 할 수 없습니다. 첫 번째 청크 만 얻고 더 이상 읽지는 않습니다. –

관련 문제