Ошибка сброса соединения для больших полезных нагрузок - PullRequest
0 голосов
/ 20 марта 2019

У меня есть очень простое тестовое приложение, которое обслуживает байты из памяти и возвращает его клиенту.

Всякий раз, когда я пытаюсь отправить запрос на размер байта, превышающий 2 ГБ, я получаю сброс соединенияошибка в коде моего сервера и ошибка 502 в консоли chrome.Ниже 2 гб работает нормально.

На моей стороне клиента я выполняю сценарий Java, который я выполняю из браузера.Это в основном выполняет XMLHTTPRequest, получает ответ (сохраняется в памяти браузера) и запрашивает сохранение.

Хотелось бы узнать, почему происходит ошибка.Это потому, что лимит памяти для вкладки браузера превышен?

Ниже приведен код на стороне сервлета или сервера

protected void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
 try {
String param = request.getParameter("size");
if (param != null) {

  int kByte = Integer.parseInt(param);

  response.setContentType("application/octet-stream");
  response.setContentLength(kByte * 1024);

  ServletOutputStream outputStream = response.getOutputStream();
  byte[] buffer = new byte[1024];
  Random random = new Random(System.currentTimeMillis());

  long size = 0;
  while (size < kByte) {
    random.nextBytes(buffer);
    outputStream.write(buffer);
    size += 1;
  }

  outputStream.flush();

  return;
}
 }catch (Exception e) {
     e.printStackTrace();
     response.sendError(500, e.getMessage());
     return;
 }

}

Ниже приведен тестовый клиент на Javaкод сценария

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href='https://fonts.googleapis.com/css?family=Titillium+Web:400' rel='stylesheet' type='text/css'>
<style type="text/css">

body {
    margin: 0;
    font-family: "Titillium Web";
    font-size: 15px;
}

#demo-container {
    width: 400px;
    margin: 60px auto;
}

#download-button {
    background-color: white;
    color: #2980b9;
    border: 2px solid #2980b9;
    font-family: inherit;
    outline: none;
    min-width: 100px;
    padding: 10px;
    font-size: inherit;
    border-radius: 2px;
    cursor: pointer;
    display: block;
    margin: 0 auto;
}

#start-download {
    text-align: center;
    display: none;
}

#download-progress-container {
    border: 1px solid #cccccc;
    padding: 4px;
    display: none;
    height: 20px;
}

#download-progress {
    background-color: #2980b9;
    display: inline-block;
    height: 100%;
}

#save-file {
    color: #2980b9;
    text-decoration: none;
    display: none;
    text-align: center;
}

#save-file:hover {
    text-decoration: underline;
}

</style>
</head>

<body>

<div id="demo-container">
    <button id="download-button">Download</button>
    <div id="download-ui-container">
        <div id="start-download">Starting Download..</div>
        <div id="download-progress-container"><div id="download-progress"></div></div>
        <a id="save-file">Save File</a>
    </div>
</div>

<script>

var _OBJECT_URL;

document.querySelector('#download-button').addEventListener('click', function() {
    var request = new XMLHttpRequest();

       request.onload = function () {
       _OBJECT_URL = URL.createObjectURL(request.response);

            document.querySelector('#save-file').setAttribute('href', _OBJECT_URL);
            document.querySelector('#save-file').setAttribute('download', 'networkTester');

            document.querySelector('#save-file').style.display = 'block';
            document.querySelector('#download-progress-container').style.display = 'none';

            setTimeout(function() {
                window.URL.revokeObjectURL(_OBJECT_URL);

                document.querySelector('#download-button').style.display = 'block';
                document.querySelector('#save-file').style.display = 'none';
            }, 60*1000);
       }


    request.responseType = 'blob';
    //request.open('get', 'img.jpeg'); 


    request.open('get', 'server url?size=4000000');

    request.send(); 
});

</script>

</body>
</html>

Трассировка стека на стороне сервера

    2019-03-20T10:32:28.501+0000 [APP/PROC/WEB/0] ERR org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:364)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:833)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:738)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:399)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:377)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.saurav.cpcftester.NetworkTester.doGet(NetworkTester.java:52)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:364)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:170)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at com.sap.xs.java.valves.ErrorReportValve.invoke(ErrorReportValve.java:66)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at com.sap.xs.security.UserInfoValve.invoke(UserInfoValve.java:19)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at com.sap.xs.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:43)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at com.sap.xs.logging.catalina.RuntimeInfoValve.invoke(RuntimeInfoValve.java:40)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:679)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at java.lang.Thread.run(Thread.java:836)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR Caused by: java.io.IOException: Connection reset by peer
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:50)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at sun.nio.ch.IOUtil.write(IOUtil.java:65)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:478)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1306)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:726)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:496)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:434)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:623)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:127)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:225)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.coyote.Response.doWrite(Response.java:602)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:352)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR   ... 39 more

С наилучшими пожеланиями,

Саурав

1 Ответ

1 голос
/ 20 марта 2019

Возможно, вы встретились с целочисленным переполнением.В частности, строка:

response.setContentLength(kByte * 1024);

может принимать целочисленный диапазон со знаком, поэтому 2^31-1 = (2147483647 bytes), что в вашем случае может вызвать переполнение.

Вы можете попытаться исправить это следующим образом:

long length = kByte * 1024; 
if (length <= Integer.MAX_VALUE) 
{ 
  response.setContentLength((int)length); 
} 
else 
{ 
  response.addHeader("Content-Length", Long.toString(length)); 
} 

, как объяснено в справочнике .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...