2

우리는 Zuul을 사용하여 요청을 내부 마이크로 서비스로 전달합니다. 내부 서비스에는 2 개의 엔드 포인트 (PUT 엔드 포인트와 POST 엔드 포인트)가 있습니다. 멀티 파트 요청이 내부 PUT 끝점에 도달하기 전에 손상된 것으로 나타났습니다.멀티 파트가있는 PUT 요청이 Zuul/DispatcherServlet에 의해 손상되었습니다 (멀티 파트 데이터가 제거됨)

요청에서 다중 파트 데이터가 제거 된 것 같습니다. 이것은 POST가 완벽하게 작동하기 때문에 PUT 요청의 경우 인 것 같습니다.

cURL을 사용하여 내부 PUT 끝점에 직접 도달하면 요청이 올바르게 처리됩니다. 해당 curl 명령 및 요청 체는 다음과 같이 :

curl -v -X PUT -H "Content-Type: multipart/form-data" -F "[email protected]/path/to/file.txt" "http://localhost:8081/file/put" 

헤더 :

{사용자 에이전트 = 컬/7.35.0, 호스트 = 로컬 호스트 : 8082], 수락 = [/], content-length = [203], expect = [100-continue], content-type = [multipart/form-data; 경계 = ------------------------ c1efb86a9054e387]}

엔티티 :

----------- --------------- c1efb86a9054e387 내용 - 처분 : 양식 데이터; name = "file"; 파일 이름 = "helloworld.txt"콘텐츠 유형 : 텍스트/

일반이 ----------------------- 내 파일 내용

입니다 우리가 Zuul를 통해 컬과 PUT 엔드 포인트를 공격하려고하면 --- c1efb86a9054e387--

그러나, 요청은 다음과 같습니다

curl -X PUT -H "Content-Type: multipart/form-data" -F "[email protected]/path/to/file.txt" "http://localhost:8082/file/put" 

헤더 :

{user-agent = [curl/7.35.0], accept = [/], 예상 = [100 연속], content-type = [multipart/양식 데이터, 경계 = hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd], x-forwarded-host = [localhost : 8081], x-forwarded-proto = [http], x-forwarded-prefix = [/ file], x-forwarded-port = [8081], x-forwarded-for = [127.0.0.1] 수락 부호화 = GZIP, 콘텐츠 길이 = [38] = 호스트 [로컬 호스트 : 8082], 연결 = 연결 유지]}

엔티티 :

--hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd--

엔터티가 불완전합니다.

이 저장소에 예제 코드를 업로드했습니다 : https://github.com/trcodestore/zuul-put-demo. 저장소에는이 문제를 설명하는 데 사용되는 2 개의 작은 프로젝트가 포함되어 있습니다. readme에는 빌드 및 실행 지침이 들어 있습니다.

요청은 처음에는 Spring의 DispatcherServlet에 의해 처리되고 결국에는 ZuulServlet에 의해 처리된다는 것을 알고 있습니다. 문제를 일으키는 DispatcherServlet이라고 생각합니다. 우리는 모든 요청 URI에 "/ zuul"을 접두사로 붙이면 DispatcherServlet을 우회 할 수 있습니다. 다중 요청이 ZuulServlet으로 직접 이동 한 다음 예상대로 작동합니다. 그러나 이것은 이상적인 해결책이 아닙니다.

모든 조언을 주시면 감사하겠습니다. 감사.

답변

3

좋아요, 해결책이 있습니다 (credit: Mohammad Zolmajd).

스프링 부트는 멀티 파트를 처리하기 위해 StandardServletMultipartResolver을 사용합니다. 이는 모든 멀티 파트 요청이 POST와 함께 제출 될 것이라고 가정합니다.

StandardServletMultipartResolver가 PUT 요청을 처리 할 수있게하려면 isMultiPart 메서드를 재정의해야합니다. 다음 구성을 사용하여 종료되었습니다.

@Bean 
public MultipartResolver multipartResolver() { 
    return new StandardServletMultipartResolver() { 
    @Override 
    public boolean isMultipart(HttpServletRequest request) { 
     String method = request.getMethod().toLowerCase(); 
     if (!Arrays.asList("put", "post").contains(method)) { 
      return false; 
     } 
     String contentType = request.getContentType(); 
     return (contentType != null &&contentType.toLowerCase().startsWith("multipart/")); 
    } 
    }; 
}