2011-08-11 5 views
3

Apache Tomcat/6.0.18Firefox에서 청크 분할 전송 인코딩이 존중되지 않는 이유는 무엇입니까?

에서 실행중인 대형 MVC 컨트롤러를 통해 큰 문서를 스트리밍하려고합니다. 크기가 크고 (결국) 동적으로 생성되기 때문에 청크 분할 전송 인코딩을 사용하기로 결정했습니다. 나는이 파이어 폭스에 열 때

import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.inject.Inject; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.httpclient.ChunkedOutputStream; 
import org.apache.commons.net.io.CopyStreamException; 
import org.apache.commons.net.io.Util; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 

@Controller 
public class QueryController { 

    @Inject 
    QueryService queryService; 

    @RequestMapping(value = "/stream") 
    public void hellostreamer(HttpServletResponse response) throws CopyStreamException, IOException { 

     response.setHeader("Transfer-Encoding", "chunked");  
     response.setHeader("Content-type", "text/xml"); 
     InputStream filestream = new FileInputStream("/lotsrecs.xml");  
     ChunkedOutputStream chunkStream = new ChunkedOutputStream(response.getOutputStream());  
     Util.copyStream(filestream,chunkStream); 
     chunkStream.close(); 
     chunkStream.finish(); 
    } 
} 

그러나,이 얻을 :

청크를 읽는 것은 그 스트림의 일부로, 읽기, 스트림에 대한 메타 데이터로 크기보다는
XML Parsing Error: syntax error 
Location: http://localhost:8082/streaming-mockup-1.0-SNAPSHOT/stream 
Line Number 1, Column 1: 

800 
^ 

! 라이브 HTTP 헤더를 사용

, 나는 전송-Encoding 헤더가 수신되고 있음을 볼 수 있습니다

HTTP/1.1 200 OK 

Server: Apache-Coyote/1.1 

Transfer-Encoding: chunked 
Content-Type: text/xml 

Date: Thu, 11 Aug 2011 18:08:07 GMT 

그래서 나는 청크 크기는 올바르게 해석되지 않는 이유에 대한 손실에 있어요. wget을 사용하여 요청을하면 반환 된 문서 안에 청크 크기 문자가 표시되므로 어떻게 든 제대로 인코딩되지 않습니다. 누구나 왜 그런 생각이 들까?

wireshark를 사용하여 전송을 봅니다 (스트림 전체에서 "800"이 반복됨). ChunkedOutputStream 클래스에서 사용되는 기본 청크 크기 인 0x800 = 2048에 유의하십시오. 이 청크 경우

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0 
User-Agent: Wget/1.12 (linux-gnu) 
Accept: */* 
Host: localhost:8082  
Connection: Keep-Alive 

HTTP/1.1 200 OK  
Server: Apache-Coyote/1.1  
Transfer-Encoding: chunked  
Content-Type: text/xml  
Date: Thu, 11 Aug 2011 18:51:05 GMT  
Connection: close  

<records> 
    <REC> 
    <FUID>412286284WOS1</FUID> 
    <UID>WOS:000292284100013</UID> 
    <static_data> 
     <summary> 

그래서 어떻게 알 수 있습니까 :

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0  
User-Agent: Wget/1.12 (linux-gnu)  
Accept: */*  
Host: localhost:8082  
Connection: Keep-Alive 

HTTP/1.1 200 OK  
Server: Apache-Coyote/1.1  
Transfer-Encoding: chunked  
Content-Type: text/xml  
Date: Thu, 11 Aug 2011 18:47:24 GMT  
Connection: close 

800 

<records> 
    <REC> 
    <FUID>412286284WOS1</FUID> 
    <UID>WOS:000292284100013</UID> 
    <static_data> 
     <summary> 
     <EWUID uid="WOS:000292284100013" year="2011"> 

난 그냥 출력 스트림에 복사하는 경우 직접 ChunkedOutputStream을 만들지 않고, 난 전혀 청크 크기를 표시되지 않는 이유는 무엇입니까? 만약 그렇다면, 청크 크기를 보지 않겠습니까?

+0

'연결 : 닫기'는 작동하지 않는 신호가 있음을 나타냅니다. –

답변

11

직접 ChunkedOutputStream을 구성해야합니까?

실무에 익숙하지 않은 점은 클라이언트가 HTTP 1.0이 아닌 경우 ServletResponse.getOutputStream()이 청크를 처리해야한다는 것입니다 (예 : 클라이언트가 HTTP 1.0이 아닌 경우). 이것이 사실이라면 실제로 전송 된 응답은 청크 분할 인코딩으로 청크 분할되며 브라우저는 물론 이들 계층 중 하나만을 알고 있습니다.

네트워크를 통해 어딘가에서 서버를 실행하고 Wireshark를 사용하여 트랜잭션을 검사하려 했습니까?

업데이트 : (해당 인코딩 만 1.1 발명되면서 자연적으로 충분) 1.0 클라이언트 모두에서 청크 분할 인코딩을 이해하는 데 필요하지 않은 HTTP/

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0 

.

+0

wireshark에서 출력을 표시하도록 내 질문이 업데이트되었습니다. – nont

+0

매우 흥미 롭습니다! wget이나 curl이 HTTP 1.1을 사용하도록 강제 할 때 어떤 일이 일어나는지 보겠습니다. 감사! – nont

+0

굉장 : 컬을 사용하여 스트림을 직접 복사하면 HTTP 1.1이보고되고 예상대로 브라우저가 아닌 wireshark 스트림에서 청크 크기가 표시됩니다. 그래서 당신은 절대적으로 옳습니다 : ChunkedOutputStream을 직접 사용할 필요가 없습니다. 실제로 그렇게하면 내 스트림이 실수로 "두 번 청크"하게됩니다. – nont

관련 문제