2012-02-06 2 views
4

java (및 scala)를 사용하여 간단한 직선 클라이언트 - 서버 응용 프로그램을 개발하고 테스트하고 있습니다.큰 파일을 업로드 할 때 Apache HttpClient 4.x가 이상하게 작동합니까?

서버com.sun.net.httpserver.HttpServer을 기반으로하며 POST 및 PUT 작업을 사용하여 기본 RESTful 인터페이스를 통해 파일을 업로드 할 수 있습니다. 업로드 작업은 Google이 자체적으로 구현 한 Digest authentication을 사용하여 제한되며 브라우저에서 테스트되고 작동하며 말림 및 Apache HttpClient입니다.

업로드 클라이언트Apache HttpClient 4.1.2을 랩핑하고 파일 엔터티를 업로드하기 위해 http를 통해 PUT 작업을 실행합니다. 파일의 내용 유형은 헤더에 application/xml으로 지정되며 한 번에 하나의 파일 만 업로드됩니다.

하는 서로 다른 크기의 이상한 행동을 관찰 할 수의 파일을 업로드 할 때 : 작은 크기의

  • 파일 또는 1.076.006 바이트에 동일은 성공적으로 을 업로드됩니다.
  • 1.122.158 바이트보다 크거나 같은 파일 java.net.SocketException: Broken pipe입니다. 깨진 파이프

    이유입니다

클라이언트가 어떻게 든 무시 것으로, (I 수동으로 최대 작업 크기에 근접하는 다른 크기의 파일을 생성 한 이후 정확한 중요한 크기를 알 수 없습니다) www-authenticate- 응답 해당 크기의 파일을 업로드합니다 (서버 로그에 설명되어 있음). "무시"는 인증 헤더가없는 메시지를 여러 개 (4 개) 보내는 것을 의미합니다. 작은 파일은 잘 작동하며 클라이언트는 www-authenticate -response가되어야하는 바로 다음에 적절한 challenge-response를 사용하여 인증 요청을 올바르게 보냅니다.

모든 크기의 파일로 업로드가 제대로 작동하므로 업로드해도 문제가 없습니다.

이 시점에서 "클라이언트에 버그가 있습니다."라고 말할 수 있습니다. 좋아, 나도 그런 것 같지만 나는 오픈 소스 자바 RESTclient (또한 apache httpclient를 래핑)을 시도했으며, 정확히 같은 동작을 가지고있다!

인터넷을 통해이 클라이언트를 사용하여 시도해 보았습니다. 지금 당장은이 잘못된 행동으로 이어지는 Apache HttpClient에서 뭔가 중요한 것을 놓치기를 바랍니다. 오픈 소스 RESTclient의 개발자도 그걸 놓쳤습니다. 어떤 아이디어가 될지 상상해보십시오!

답변

6
는이 상황에 이르게 여러 가지 요인의 조합이다 대부분의 경우

(1) 대부분의 경우 클라이언트는 사용하지 않는 '- 기대 계속'하지 않는 요청 대형 요청 엔티티를 보낼 때 악수 인증 헤더를 포함합니다.

(2) 서버는 요청이 기대에 미치지 못하는 것을 먼저 감지하고 전체 요청 본문을 읽고 파기하는 대신 초기에 401 상태로 응답하고 그 끝에서 연결을 닫습니다. 제 의견으로는, 이것은 서버 측에서 HTTP 프로토콜 위반입니다.

(3) 일부 HTTP 에이전트는 초기 응답을 처리 할 수 ​​있지만 Apache HttpClient는 Java 블로킹 I/O (실행 스레드는 블로킹 소켓에서 읽거나 쓸 수 있지만 둘 다 사용할 수는 없음) .

문제를 해결할 수있는 방법은 여러 가지가 있습니다. '가장 기대되는'핸드 셰이크가 가장 쉽고 자연스러운 방법입니다. 또는 간단한 POST 또는 POST 요청을 실행하기 전에 HTTP 인증을 강제하는 간단한 HEAD 또는 GET 요청을 실행할 수 있습니다. HttpClient는 동일한 논리적 HTTP 세션에서 후속 요청에 대해 인증 데이터를 다시 사용할 수 있습니다.

+0

설명해 주셔서 감사합니다. 지금 나는 '기대 - 계속'- 해결책을 찾으러 간다. 클라이언트에서는 그냥 부울을 뒤집을뿐입니다. 서버에서의 핸드 쉐이크가 현재 작동 중입니다. 문제가 해결되어야한다는 것을 확신합니다. – mtsz

+0

이상하게도 태양 아래에있는 httpserver *는 항상 응용 프로그램을 사용하지 않고 100-continue로 응답합니다! 그것이 프로토콜에 위배되는 것 같습니다 (RFC 2616 "100 (계속) 상태 사용", httpserver-source : http://www.docjar.com/html/api/sun/net/httpserver/ServerImpl 참조). java.html). 하지만 많은 양의 데이터를 보내기 전에 두 번째 요청으로 인증을 트리거하는 두 번째 솔루션을 구현했습니다. 이 작품은 정말 고마워! – mtsz

+0

@mtsz 요즘에는 쓸모없는 HTTP 서버가 많을 때 Sun의 ServerImpl을 사용하는 이유는 무엇입니까? – oleg