Search code examples
javahttprestlet

Error with HTTP Connection: close header


I am having a weird problem with a small restlet service that I am building as an exercise. The application is supposed to respond with some XML (specifically TwiML, as it is meant for Twilio) on an HTTP POST, and it worked well for standalone requests. However, when requested by Twilio, the response never completes and it times out. After comparing the traffic coming from Twilio with the one that is working (using a fake HTML form), I isolated the issue to the "Connection: close" header and can reproduce it using nothing but curl command-line. Here is the request that works:

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

and here is the one that just hangs:

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

If I kill the server then curl says "(52) Empty reply from server". Here is the code that I am using in the 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;
}

Is something obviously wrong with what I am doing here? I am using restlet-2.0, but also tried with 2.1m1 with the same result. I would really appreciate a quick response as I am on a deadline to finish the exercise.


Solution

  • not sure if you found a solution for your error, but I came across the same problem in Restlet V 2.0.4.

    When running the restlet using the default server. Here the server does assume that the response stream is not writable and thus will not respond with an entity.

    As a quick fix I located

      org.restlet.engine.http.connector.Connection
    

    and changed the the canWrite() method to

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

    from the original

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

    Not sure if that is a good fix, but after recompiling the restlet module it now seems to work fine. It seems to be the issue that when specifying the HTTP Header 'Connection: close' the stream is by default in closing state.

    Hope that helps

    Joey

    See here for the problem on the restlet forum

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