내부적으로 HttpsUrlConnection을 사용하여 다른 Url을 호출하는 서블릿을 작성하고 있습니다. 서블릿에서 HttpsUrlConnection 호출에서받은 것과 동일한 응답과 동일한 응답 헤더를 반환해야합니다.
이를 위해 다음을 사용하여 모든 헤더를 읽었습니다 getHeaderFields()
. 내 서블릿의 Httpservletresponse 객체에 반환 된 헤더를 복사합니다.
또한, 그 후 응답을 읽으려고합니다 connection.getErrorStream()
(이것은 대부분 서버가 400을 반환 할 때 발생합니다). 그래서 getErrorStream을 사용합니다. 그런 다음 바이트를 읽고 서블릿의 HttpServletResponse 출력 스트림에 바이트를 복사합니다.
이제 이것은 잘 작동하는 경우가 있습니다.
그러나 연결을 사용하여 호출하는 서버가 Transfer Encoding 청크로 응답을 반환하면 서블릿 API를 호출 할 때 응답 및 응답 헤더를 Httpservlet 응답에 복사하면 잘못된 청크 인코딩에 대한 오류가 반환됩니다.
이 경우 로그에서 getHeaderFields를 사용하여 헤더를 읽을 때 내가 보는 첫 번째 헤더는 Transfer encoding chunked이고 다음 헤더 이름은 null이고 값은 HTTP 1/1입니다.
또한 내가 본 반응도 적절하지 않습니다.
이 경우 httpsurlconnection에서 응답 헤더와 응답 본문을 읽고 서블릿에서 올바르게 반환하는 방법은 무엇입니까?
청크 인코딩과 비슷한 문제가 발생했습니다. 차이점은 내 서블릿이 내부적으로 HTTPS 대신 HTTP를 사용한다는 것입니다.
헤더 필드를 복사하는 방법도 사용합니다. 하지만 서블릿 컨테이너에서 관리하는 헤더 목록을 제공하므로 생성, 복사 또는 편집하지 않습니다.
private static final Set forbiddenCopyHeaders = new HashSet<>(Arrays.asList(new String[]{
"connection"
, "transfer-encoding"
, "content-length"
, "via"
, "x-forwarded-for"
, "x-forwarded-host"
, "x-forwarded-server"
}));
응답 헤더를 복사하는 데 사용하는 방법은 다음과 같습니다.
private void copyResponseHeaders(CloseableHttpResponse internResponse, HttpServletResponse response)
{
Header[] headers = internResponse.getAllHeaders();
Header[] connHeaders = internResponse.getHeaders("connection");
StringBuilder connectionValue = new StringBuilder();
for (Header connHeader : connHeaders)
{
connectionValue.append(connHeader.getValue()).append(", ");
}
for (Header header : headers)
{
String headerName = header.getName();
boolean copyAllowed = !forbiddenCopyHeaders.contains(headerName.toLowerCase())
&& !StringUtils.containsIgnoreCase(connectionValue.toString(), headerName);
if (copyAllowed)
{
if (response.containsHeader(headerName))
{
response.addHeader(headerName, header.getValue());
}
else
{
response.setHeader(headerName, header.getValue());
}
}
}
setViaHeader(internResponse, response);
}
setViaHeader () 메소드 :
private void setViaHeader(CloseableHttpResponse response, HttpServletResponse customerResponse)
{
String serverHostName = "companyServer";
try
{
serverHostName = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
logger.error("für den VIA-Header kann der Hostname nicht ermittelt werden", e);
System.err.println("für den VIA-Header kann der Hostname nicht ermittelt werden: " +
ExceptionUtils.getStackTrace(e));
}
Header[] originalViaHeaders = response.getHeaders("via");
StringBuilder via = new StringBuilder("");
if ((originalViaHeaders != null) && (originalViaHeaders.length > 0))
{
for (Header viaHeader : originalViaHeaders)
{
via.append(viaHeader.getValue()).append(", ");
}
}
via.append(response.getStatusLine().getProtocolVersion().toString()).append(" ").append(serverHostName);
customerResponse.setHeader("via", via.toString());
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다