java.io.IOException:Apache Tomcat阀门中的管道损坏

时间:2016-04-29 03:23:38

标签: java tomcat servlets

我正在开发基于SAML 2.0的单点登录Apache Tomcat阀门。在测试我的实现时,我会发现以下一组错误,这些错误似乎是间歇性地发生在通过阀门的某些请求中。

28-Apr-2016 23:29:50.798 SEVERE [http-nio-8080-exec-1] org.wso2.appserver.webapp.security.saml.SAMLSingleSignOn.invoke An error has occurred when processing the request
 org.wso2.appserver.webapp.security.utils.SSOException: Error occurred while writing to HttpServletResponse
    at org.wso2.appserver.webapp.security.saml.SAMLSSOManager.sendCharacterData(SAMLSSOManager.java:299)
    at org.wso2.appserver.webapp.security.saml.SAMLSingleSignOn.handleUnauthenticatedRequest(SAMLSingleSignOn.java:212)
    at org.wso2.appserver.webapp.security.saml.SAMLSingleSignOn.invoke(SAMLSingleSignOn.java:127)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:393)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:426)
    at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:342)
    at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:317)
    at org.apache.catalina.connector.Response.flushBuffer(Response.java:510)
    at org.wso2.appserver.webapp.security.saml.SAMLSSOManager.sendCharacterData(SAMLSSOManager.java:296)
    ... 12 more
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
    at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:124)
    at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
    at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:172)
    at org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:139)
    at org.apache.coyote.http11.InternalNioOutputBuffer.addToBB(InternalNioOutputBuffer.java:197)
    at org.apache.coyote.http11.InternalNioOutputBuffer.access$000(InternalNioOutputBuffer.java:41)
    at org.apache.coyote.http11.InternalNioOutputBuffer$SocketOutputBuffer.doWrite(InternalNioOutputBuffer.java:320)
    at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:116)
    at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:256)
    at org.apache.coyote.Response.doWrite(Response.java:501)
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:388)
    ... 17 more 

这似乎发生在我编写HTML有效内容时,其中包含要发送的SAML 2.0请求内容。用于上述情况的代码如下:

private void handleUnauthenticatedRequest(Request request, Response response,
            SSOAgentRequestResolver requestResolver) throws SSOException {
        SAMLSSOManager manager = new SAMLSSOManager(agentConfiguration);

        //  handle the generation of the SAML 2.0 RelayState
        String relayStateId = SSOUtils.createID();
        RelayState relayState = SSOUtils.generateRelayState(request);
        if (agentConfiguration != null) {
            agentConfiguration.getSAML2().setRelayState(relayStateId);
        }
        Optional.ofNullable(request.getSession(false))
                .ifPresent(httpSession -> httpSession.setAttribute(relayStateId, relayState));

        //  TODO: check if the isPassive option of wso2as-web.xml can be removed since this is overridden here + usage
        Optional.ofNullable(agentConfiguration)
                .ifPresent(agent -> agent.getSAML2().enablePassiveAuthenticationEnabled(false));
        if (requestResolver.isHttpPOSTBinding()) {
            containerLog.info("Handling the SAML 2.0 Authentication Request for HTTP-POST binding...");
            String htmlPayload = manager.handleAuthnRequestForPOSTBinding(request);
            manager.sendCharacterData(response, htmlPayload);
        } else {
            containerLog.info("Handling the SAML 2.0 Authentication Request for " +
                    agentConfiguration.getSAML2().getHttpBinding() + "...");
            try {
                response.sendRedirect(manager.handleAuthnRequestForRedirectBinding(request));
            } catch (IOException e) {
                throw new SSOException("Error when handling SAML 2.0 HTTP-Redirect binding", e);
            }
        }
    }

sendCharacterData方法将有效负载写入响应主体。

protected void sendCharacterData(HttpServletResponse response, String htmlPayload) throws SSOException {
    try {
        Writer writer = response.getWriter();
        writer.write(htmlPayload);
        response.flushBuffer();
        //  not closing the Writer instance, as its creator is the HttpServletResponse
    } catch (IOException e) {
        throw new SSOException("Error occurred while writing to HttpServletResponse", e);
    }
}

大多数资源提供的解决方案似乎没有提供任何帮助。任何有关此场景的帮助都将受到高度赞赏。

0 个答案:

没有答案