【问题标题】:Error with HTTP Connection: close headerHTTP 连接错误:关闭标头
【发布时间】:2010-12-20 03:06:34
【问题描述】:

我正在构建一个作为练习的小型 restlet 服务有一个奇怪的问题。该应用程序应该在 HTTP POST 上使用一些 XML(specifically TwiML,因为它适用于 Twilio)来响应,并且对于独立请求来说效果很好。但是,当 Twilio 请求时,响应永远不会完成并且会超时。在将来自 Twilio 的流量与正在运行的流量(使用伪造的 HTML 表单)进行比较后,我将问题隔离到“连接:关闭”标题,并且可以使用 curl 命令行来重现它。这是有效的请求:

curl -i -H 'Connection: keep-alive' -X POST -d "name=value" http://localhost:8020/hello

这是一个刚刚挂起的:

curl -i -H 'Connection: close' -X POST -d "name=value" http://localhost:8020/hello

如果我终止了服务器,那么 curl 会说“(52) 来自服务器的空回复”。这是我在 ServerResource 中使用的代码:

@Post
public Representation hello(Representation repr)
{
    Representation result = new StringRepresentation(("<Response>\n"+
            "   <Say>Hello. This is a test.</Say>\n"+
            "</Response>"), MediaType.APPLICATION_XML);
    return result;
}

我在这里所做的事情明显有问题吗?我正在使用restlet-2.0,但也尝试使用2.1m1,结果相同。我非常感谢您的快速响应,因为我在最后期限内完成练习。

【问题讨论】:

    标签: java http restlet


    【解决方案1】:

    不确定您是否找到了错误的解决方案,但我在 Restlet V 2.0.4 中遇到了同样的问题。

    使用默认服务器运行 restlet 时。这里服务器确实假设响应流不可写,因此不会响应实体。

    作为一个快速修复我找到了

      org.restlet.engine.http.connector.Connection
    

    并将 canWrite() 方法更改为

    public boolean canWrite() { 
        return (
                 (getState() == ConnectionState.OPEN) 
                         || (getState() == ConnectionState.CLOSING)) 
                && !isOutboundBusy() 
                && (getOutboundMessages().size() > 0); 
    } 
    

    来自原文

    public boolean canWrite() { 
        return (getState() == ConnectionState.OPEN) && !isOutboundBusy() 
                && (getOutboundMessages().size() > 0); 
    }
    

    不确定这是否是一个好的修复,但在重新编译 restlet 模块后,它现在似乎工作正常。 似乎是在指定 HTTP 标头“连接:关闭”时,流默认处于关闭状态的问题。

    希望有帮助

    乔伊

    在restlet论坛上查看这里的问题

    http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2698048

    【讨论】:

    • 感谢分享。这是否意味着,restlet 不能很好地处理具有“Connection: close”标头的连接(这将是一个重大错误)?
    • 嗯,它似乎是与 restlet 捆绑在一起的标准 restlet 服务器的人工制品。我假设如果你在不同的容器(例如 Jetty)中部署你的 restlet,它不会遇到这个问题。但同意,这绝对是一个错误。
    • 打开三年后,错误仍然存​​在......感谢您的诊断和解决方法。
    • 似乎已在最新版本中修复 - 我有这个库的旧版本有这个错误,升级到最新的 .jar 修复了它。
    【解决方案2】:

    不确定是不是这样,但需要考虑以下几点:

    Restlet 非常仔细和准确地实现了 REST 架构风格。它实现的关键 REST 原则之一是统一接口。在基于 HTTP 的 Web 服务中,统一接口以最初预期的方式利用 HTTP GET、PUT、POST、DELETE(和其他)操作。因此,要在分配资源名称时在服务器上创建资源,请使用 PUT。要更新该资源,您再次使用 PUT。要阅读它,请使用 GET。要删除它,请使用 DELETE。当服务器分配资源名称时,POST保留用于创建资源。

    所以这可能是由于预期不匹配造成的。 POST 通常具有您要发送到服务器的表示,但此 POST 没有。您是否正在阅读完整的请求并在服务器端正确关闭连接?

    【讨论】:

    • 除了创建应用程序和组件之外,我并没有特别针对连接做任何事情,我希望restlet 能够处理它。关于代表,我不是很清楚它是如何工作的,而且我很难找到直截了当的文档(我承认,我现在很着急),但由于我没有发送任何代表,我是否需要做任何事情特别的?我将检查不读取表单参数是否会导致restlet进入等待状态。我检查了堆栈转储,没有一个堆栈指向甚至 restlet 代码。
    猜你喜欢
    • 2011-04-05
    • 2022-01-07
    • 1970-01-01
    • 2013-09-20
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多